diff --git a/COPYING b/COPYING deleted file mode 100644 index 5b6e7c66c2..0000000000 --- a/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/INSTALL.txt b/INSTALL.txt deleted file mode 100644 index ef406a4845..0000000000 --- a/INSTALL.txt +++ /dev/null @@ -1,39 +0,0 @@ - Autopsy Forensic Browser - http://www.sleuthkit.org/autopsy - - Brian Carrier [carrier@sleuthkit.org] - Last Update: March 2010 - - -Installation ------------------------------------------------------------------------------ -1. Install The Sleuth Kit (see README for download locations). This - includes doing a 'make install' so that the executables and files - are installed in a single directory. Note that this does not - currently work natively on Windows. It will work using Cygwin, but - you must install and build The Sleuth Kit in Cygwin and not use the - Win32 executables that are available on the sleuthkit.org website. - -2. Untar the Autopsy file. - -3. Run 'make'. It will try to locate the grep and strings utilities. - If any are not found, it will prompt you for the location. It will - also search for the TSK installation. - -4. The install script will ask if you have the NIST National Software - Reference Library (NSRL). If you do, you will need to enter the - path of it. The NSRL is available from www.nsrl.nist.gov. - -5. You will be prompted for the Evidence Locker location. This is the - base directory where all cases will be stored. You must create this - directory on your own. - - -Live Analysis ------------------------------------------------------------------------------- -Type 'make live' or run the 'make-live-cd' script to build the 'live-cd' -directory. The 'live-cd' directory can be burned to a CD. - ------------------------------------------------------------------------------- -Brian Carrier [carrier@sleuthkit.org] - diff --git a/Makefile b/Makefile deleted file mode 100644 index 3a6334c196..0000000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -all: - @sh ./configure - -conf.pl: - @sh ./configure - -live: conf.pl - ./make-live-cd - -indent: - cd lib; perltidy -b *.pm *.pl - cd base; perltidy -b autopsy.base - -clean: - rm -f ./autopsy - rm -f ./make-live-cd - rm -f ./conf.pl - rm -f ./config.tmp - rm -f ./config2.tmp - rm -rf ./live-cd/ - rm -f ./lib/*.bak - rm -f ./base/*.bak - find . -name ".DS_Store" | xargs rm -f - find . -type f -perm +g+x,o+x,u+x | xargs chmod -x - grep "curtskver=" ./configure - grep "VER" ./lib/define.pl - find . -name ".*" | grep -v perltidy - -release: - find . -name "CVS" | xargs rm -rf diff --git a/CHANGES.txt b/NEWS.txt similarity index 100% rename from CHANGES.txt rename to NEWS.txt diff --git a/README-LIVE.txt b/README-LIVE.txt deleted file mode 100644 index df1aaabdc6..0000000000 --- a/README-LIVE.txt +++ /dev/null @@ -1,119 +0,0 @@ - Autopsy Forensic Browser - http://www.sleuthkit.org/autopsy - - Live Analysis Mode - - Last Updated: January 2005 - - -What is Live Analysis? --------------------------------------------------------------------- -Live analysis is, in my mind, an investigation that occurs using -the software resources of the suspect system. An example scenario -of this is when a suspect system is found running, a CD is placed -into it, and commands are run. If the suspect system is powered -down and booted from a bootable Linux CD (or similar), then the -investigation is a dead analysis. - -This is most commonly done when investigating a server or other -computer that is suspected of being compromised, but verification -is needed before it can be powered down. Using The Sleuth Kit and -Autopsy will prevent the access times on individual files from being -updated (although the raw device's A-time will be) and can bypass -most rootkits that hide files and directories. - - -What are the Issues with Live Analysis? --------------------------------------------------------------------- -Live analysis is not ideal because you are relying on the suspect -system, which can lie, cheat, and steal. In addition to the potential -of getting false information from the operating system you will -also overwrite memory and maybe swap space during the investigation. - -If you are interested in examining the memory of the system, you -should probably acquire that before you begin a live analysis. - -An issue with doing live analysis with Autopsy is that it requires -Perl, which is a large program and will likely need to depend on -libraries and other files on the suspect system. - - -How do I make a CD with Autopsy on it? --------------------------------------------------------------------- - -You will want to have a trusted CD for a live analysis, and autopsy -makes that fairly easy. Compile autopsy as you would for a normal -dead analysis installation. Then execute 'make live' in Autopsy. -This script will make a 'live-cd' sub-directory in the autopsy directory, -which contains a copy of autopsy and copies of TSK executables, grep, -strings, perl etc: - - # make live - Making base directory (./live-cd/) - Copying executables - Copying autopsy files - Creating configuration file using existing settings - -Try the 'make static' with TSK to see if you can make static -executables for your platform. - -The 'live-cd' directory has a 'bin' directory where additional -executables can be copied to and then the whole directory can be -burned to a CD. - - -How Do I Use the CD? --------------------------------------------------------------------- - -After the CD has been created and there is a system suspected of -being compromised, then it is time to take advantage of the new -features. There are two scenarios for live analysis. The first -scenario uses a network share from a trusted system that you can -write to. In this case, autopsy is run as normal and you specify -the evidence locker directory as the mounted disk. The evidence -locker is specified with '-d': - - # ./autopsy -d /mnt/ev_lock 10.1.32.123 - -The above would start autopsy, use '/mnt/ev_lock/' as the evidence -locker and would allow connections from 10.1.32.123 (where the -investigator would connect from using an HTML browser). Remember that -we do not want to write to the suspect system, so we should only use -a network share and not a local directory in this scenario. - -The second scenario does not use an evidence locker and does not -intentionally write any data to disk. This scenario does not need -the network share and each of the devices (or partitions) that will -be analyzed are specified on the command line using the '-i' flags. -The '-i' flag requires three arguments: the device, the file system -type, and the mounting point. For example, to examine the '/dev/hda5' -and '/dev/hda8' partitions on a Linux system, the following could -be used: - - # ./autopsy -i /dev/hda5 linux-ext3 / -i /dev/hda8 linux-ext3 /usr/ \ - 10.1.32.123 - -The file system type must be one of the types that are supported -by TSK. The remote IP address must also be given, otherwise you -will have to use a browser on the suspect system and that will write -data to the disk. - -When you use the '-i' flag, then autopsy will start in the 'Host -Manager' view where you can select the image that you want to -analyze. You will skip the case and host configuration. The default -case name will be 'live', the default host name is 'local', and the -default investigator name is 'unknown'. - - -Additional Information --------------------------------------------------------------------- -I wrote a more detailed explanation of the live analysis mode of -Autopsy version 2.00 in the 13th issue of The Sleuth Kit Informer. -Some of this document is taken from the Informer issue. - - http://www.sleuthkit.org/informer/sleuthkit-informer-13.html - - --------------------------------------------------------------------- -Copyright (c) 2004 by Brian Carrier. All Rights Reserved -Brian Carrier [carrier sleuthkit org] diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index d8a262840f..0000000000 --- a/TODO.txt +++ /dev/null @@ -1,58 +0,0 @@ -Remove HFS check in autopsy.base when HFS support is standard. - -Look into adding the unallocated partiion space when an image is added. -Look into integrating clamshell or other AV - -There is an error when viewing the event sequencer notes about -initialized in "ne". - -test date search - -Add SHA-1 to more places (images, lookups etc.) - -Get "Can't ignore signal CHLD, forcing to default." message with -file type sorting (BUG: 919829). - -Figure out details around having Perl on the live analysis CD. -(BUG: 919831) - - --------------------- FILE MODE ---------------------------- -- Make a file system depend seperator for / or \ - -- check for tar during install - - List contents like HTML does now - ---------------------- SEARCH ----------------------------- -- new mode where searching is done on output of 'icat' of allocated - inodes - -- Bug: if the string that matches a keyword starts with spaces, then - the 'index' function returns the idx to the start of the spaces and not - the substring. (BUG 842858) - ---------------------- TIMELINE ----------------------------- - - ---------------------- LOGGING ----------------------------- -- New Report Creation: - -- Add pulldown in notes for common things: - - New MD5 / SHA-1 - - Part of rootkit - - Suspected child porn - - known child porn - ---------------------- SORTER ----------------------------- -- Should sorter be at the host level instead of image, with output -files appended to each other? - -- Allow one to browse output files - ---------------------- GENERAL ----------------------------- -- Add foremost -- link in meta data to list just unallocated / used -- Make data bases updatable in the host details view -- Option to mount images in loopback when it is a Linux system -- read config files in autopsy itself and not everytime ... -- Make a way to kill intensive processes (searching, fls) diff --git a/base/.perltidyrc b/base/.perltidyrc deleted file mode 100755 index f1f2e71a01..0000000000 --- a/base/.perltidyrc +++ /dev/null @@ -1,5 +0,0 @@ --i=4 # indent of 4 --pt=2 # paren tightness --sbt=2 # square paren tightness --bt=2 # curly paren tightness --nsfs # no space after semi in for loop diff --git a/base/autopsy.base b/base/autopsy.base deleted file mode 100644 index 3b3bbdc7f2..0000000000 --- a/base/autopsy.base +++ /dev/null @@ -1,879 +0,0 @@ -# -# autopsy gui server -# Autopsy Forensic Browser -# -# -# This file requires The Sleuth Kit -# www.sleuthkit.org -# -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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.008; - -use strict; -use Socket; - -use Main; -use Print; -require Fs; -require Caseman; - -require 'conf.pl'; -require 'lib/define.pl'; - -# Import variables from conf.pl -use vars '$LOCKDIR', '$INSTALLDIR', '$PICTDIR'; -use vars '$SANITIZE_TAG', '$SANITIZE_PICT'; -use vars '$USE_STIMEOUT', '$STIMEOUT', '$CTIMEOUT'; -use vars '$SAVE_COOKIE', '$GREP_EXE', '$FILE_EXE'; -use vars '$NSRLDB'; - -# Default port -my $port = 9999; - -# Default 'remote' host -my $rema = 'localhost'; - -$| = 1; - -$::LIVE = 0; -$::USE_NOTES = 1; -$::USE_LOG = 1; - -sub usage { - print -"\n\nusage: $0 [-c] [-C] [-d evid_locker] [-i device filesystem mnt] [-p port] [remoteaddr]\n"; - print " -c: force a cookie in the URL\n"; - print " -C: force NO cookie in the URL\n"; - print " -d dir: specify the evidence locker directory\n"; - print " -i device filesystem mnt: Specify info for live analysis\n"; - print " -p port: specify the server port (default: $port)\n"; - print " remoteaddr: specify the host with the browser (default: $rema)\n"; - exit 1; -} - -my $cook_force = 0; - -my $vol_cnt = 0; - -# 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; - $cook_force = 1; - } - - # force a cookie - elsif ($f eq '-c') { - $::USE_COOKIE = 1; - $cook_force = 1; - } - - elsif ($f eq '-i') { - $::LIVE = 1; - $::USE_LOG = 0; - $::USE_NOTES = 0; - $::SAVE_COOKIE = 0; - - if (scalar(@ARGV) < 3) { - print "Missing device, file system, and mount point arguments\n"; - usage(); - } - - my $vol = "vol" . $vol_cnt; - $vol_cnt++; - - my $dev = shift; - if ($dev =~ /($::REG_IMG_PATH)/) { - $dev = $1; - } - else { - print "invalid device: $dev\n"; - usage(); - } - - unless ((-e "$dev") || (-l "$dev")) { - print "Device ($dev) not found\n"; - usage(); - } - - my $fs = shift; - if ($fs =~ /($::REG_FTYPE)/) { - $fs = $1; - } - else { - print "invalid file system: $fs\n"; - usage(); - } - unless ((exists $Fs::root_meta{$fs}) - && (defined $Fs::root_meta{$fs})) - { - print "File system not supported: $fs\n"; - usage(); - } - $Caseman::vol2ftype{$vol} = "$fs"; - - my $mnt = shift; - if ($mnt =~ /($::REG_MNT)/) { - $mnt = $1; - } - else { - print "invalid mount point: $mnt\n"; - usage(); - } - $Caseman::vol2mnt{$vol} = "$mnt"; - $Caseman::vol2cat{$vol} = "part"; - $Caseman::vol2itype{$vol} = "raw"; - $Caseman::vol2start{$vol} = 0; - $Caseman::vol2end{$vol} = 0; - - # This makes me nervous ... - $Caseman::vol2par{$vol} = $vol; - $Caseman::vol2path{$vol} = "$dev"; - $Caseman::vol2sname{$vol} = "$dev"; - } - - # Specify a different port - elsif ($f eq '-p') { - if (scalar(@ARGV) == 0) { - print "Missing port argument\n"; - usage(); - } - - my $p = shift; - if ($p =~ /(\d+)/) { - $p = $1; - } - else { - print "invalid port: $p\n"; - usage(); - } - if (($p < 1) || ($p > 65535)) { - print "invalid port: $port\n"; - usage(); - } - $port = $p; - } - - else { - print "Invalid flag: $f\n"; - usage(); - } -} - -# remote address -if (scalar(@ARGV) > 0) { - $rema = shift; -} - -# 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]); - -my $bindaddr; - -# 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"; - $bindaddr = $acl_addr[0]; - - # Force no cookie to be used unless we already set this value - # with arguments - $::USE_COOKIE = 0 unless ($cook_force == 1); -} -else { - $lclhost = `/bin/hostname`; - chop $lclhost; - - $bindaddr = INADDR_ANY; - - # Force a cookie to be used unless we already set this value - # with arguments - $::USE_COOKIE = 1 unless ($cook_force == 1); -} - -# Verify the variables defined in the configuration files -check_vars(); - -# Remove the final '/' from TSKDIR if it exists -$::TSKDIR = $1 - if ($::TSKDIR =~ /(.*?)\/$/); - -# -# Verify that all of the required executables exist -# -check_tools(); - - - -# Currently, HFS is in beta and not enabled by default. -# Autopsy has been configured for it though, so disable it if -# the user has not compiled support into TSK. remove this when -# HFS support is standard. -# This redirects stderr to stdout so we can easily capture it -my $out = `\'$::TSKDIR/fls\' -f list 2>&1`; -unless ($out =~ /hfs/) { - for (my $i = 0; $i < @Fs::types; $i++) { - if ($Fs::types[$i] eq "hfs") { - $Fs::types[$i] = ""; - last; - } - } -} - - - -# remove environment stuff that we don't need and that could be insecure -# We allow basic bin directories for CYGWIN though, since they are -# required for the CYGWIN dlls -my $UNAME = ""; -if (-e "/bin/uname") { - $UNAME = "/bin/uname"; -} -elsif (-e "/usr/bin/uname") { - $UNAME = "/usr/bin/uname"; -} - -my $ispathclear = 1; -if (($UNAME ne "") && (`$UNAME` =~ /^CYGWIN/)) { - $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin'; - $ispathclear = 0; -} -else { - $ENV{PATH} = ''; -} -delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; - -my $date = localtime; - -if ($::LIVE == 0) { - - # Remove the final '/' if it exists - $LOCKDIR = $1 - if ($LOCKDIR =~ /(.*?)\/$/); -} - -# Setup socket -my $proto = getprotobyname('tcp'); -socket(Server, PF_INET, SOCK_STREAM, $proto) - or die "Error creating network socket: $!"; - -setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1) - or die "Error setting network socket options (reuse): $!"; - -setsockopt(Server, SOL_SOCKET, SO_KEEPALIVE, 1) - or die "Error setting network socket options (keep alive): $!"; - -bind(Server, sockaddr_in($port, $bindaddr)) - or die "Error binding to port $port (is Autopsy already running?): $!"; - -listen(Server, SOMAXCONN) - or die "Error listening to socket for connections: $!"; - -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, "$cook_file") { - chmod 0600, "$cook_file"; - print COOK "$magic\n"; - close COOK; - } - else { - print "WARNING: Cannot open file to save cookie in ($cook_file)"; - } - } -} - -print < to exit -EOF2 - -Print::log_session_info("Starting session on port $port and $hn\n"); - -# Set the server alarm -$SIG{ALRM} = \&SIG_ALARM_SERVER; -$SIG{INT} = \&SIG_CLOSE; - -# setting this to ignore will automatically wait for children -$SIG{CHLD} = 'IGNORE'; - -# 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("$rip[0].$rip[1].$rip[2].$rip[3]"); - Print::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 { - my $ip = shift; - $ip = "" unless defined ($ip); - - print "HTTP/1.0 403 Forbidden$::HTTP_NL" - . "Content-type: text/html$::HTTP_NL$::HTTP_NL" - . "
\n" - . "

Access Denied

\n" - . "

Your connection from: $ip has been logged

\n" - . "
$::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" - . "
\n" - . "

Invalid URL
" - . shift() - . "

\n" - . "
" - . "$::HTTP_NL$::HTTP_NL$::HTTP_NL"; - - return; -} - -# Alarm Functions -sub SIG_ALARM_CLIENT { - Print::log_session_info("Connection timed out\n"); - close CLIENT; - exit 1; -} - -sub SIG_ALARM_SERVER { - print "Server Timeout ($STIMEOUT seconds), Exiting\n"; - Print::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"; - Print::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 () { - - last if (/^\s+$/); - - 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()); - Print::log_session_info("ERROR: Incorrect Cookie from: " - . "$rip[0].$rip[1].$rip[2].$rip[3]\n"); - forbid("$rip[0].$rip[1].$rip[2].$rip[3]"); - 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); - - my $has_ref = 0; - while () { - last if (/^\s+$/); - if (/^Referer: /) { - $has_ref = 1; - last; - } - } - - if (($has_ref == 0) && ($args ne "")) { - Print::log_session_info("ERROR: Missing referer value"); - forbid(); - return 1; - } - - # Print status - print "HTTP/1.0 200 OK$::HTTP_NL"; - ::main($args); - } - elsif ($script eq "global.css") { - show_file($script); - } - - # Display the sanitized picture or reference error - elsif ($script eq $::SANITIZE_TAG) { - Appview::sanitize_pict($args); - return 1; - } - - # Display a picture or help file - elsif (($script =~ /^(pict\/[\w\.\/]+)/) - || ($script =~ /^(help\/[\w\.\/]+)/)) - { - show_file($1); - } - elsif ($script eq 'about') { - about(); - } - - # I'm not sure why this is needed, but there are reqs for it - elsif ($script eq 'favicon.ico') { - show_file("pict/favicon.ico"); - } - else { - bad_req($url); - Print::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 =~ /\.css$/i) { - print "Content-type: text/css$::HTTP_NL$::HTTP_NL"; - } - elsif ($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 =~ /\.ico$/i) { - print "Content-type: image/ico$::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" - . "\n" - . "Error\n" - . "

Unknown Extension

\n" - . "$::HTTP_NL$::HTTP_NL$::HTTP_NL"; - exit(1); - } - - while () { - 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" - . "\n" - . "Error\n" - . "

File Not Found

" - . "$::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"; - - my $tskver = ::get_tskver(); - - print < -About Autopsy - - - -

About Autopsy

-
- \"Logo\" -

- Version: $::VER -
- http://www.sleuthkit.org/autopsy/ -
- http://www.sleuthkit.org/informer/ -
- - -

Credits

-
    -
  • Code Development: Brian Carrier (carrier at sleuthkit dot org) -
  • Interface Assistance: Samir Kapuria -
  • Mascot: Hash the Hound -
- -

Configuration

-The Sleuth Kit:
-  URL: - http://www.sleuthkit.org/sleuthkit/
-  Installation Location: $::TSKDIR
-  Version: $tskver
-Evidence Locker: $LOCKDIR
-grep: $GREP_EXE
-file: $FILE_EXE
-NIST NSRL: $NSRLDB
- - - -EOF - return 0; -} - -### Check that the required tools are there -sub check_tools { - - # Sleuth Kit execs - unless (-x $::TSKDIR . "/icat") { - print "ERROR: Sleuth Kit icat executable missing: $::TSKDIR\n"; - exit(1); - } - unless (-x $::TSKDIR . "/istat") { - print "ERROR: Sleuth Kit istat executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/ifind") { - print "ERROR: Sleuth Kit ifind executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/ils") { - print "ERROR: Sleuth Kit ils executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/fls") { - print "ERROR: Sleuth Kit fls executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/ffind") { - print "ERROR: Sleuth Kit ffind executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/blkcat") { - print "ERROR: Sleuth Kit blkcat executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/blkcalc") { - print "ERROR: Sleuth Kit blkcalc executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/blkls") { - print "ERROR: Sleuth Kit blkls executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/img_stat") { - print "ERROR: Sleuth Kit img_stat executable missing\n"; - exit(1); - } - unless (defined $::FILE_EXE) { - print "ERROR: File executable location not defined in config file\n"; - exit(1); - } - unless (-x "$::FILE_EXE") { - print "ERROR: File executable ($::FILE_EXE) missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/fsstat") { - print "ERROR: Sleuth Kit fsstat executable missing\n"; - exit(1); - } - unless (defined $::MD5_EXE) { - print "ERROR: MD5 executable location not defined in config file\n"; - exit(1); - } - unless (-x "$::MD5_EXE") { - print "ERROR: md5 executable ($::MD5_EXE) missing\n"; - exit(1); - } - if ($::SHA1_EXE ne "") { - unless (-x "$::SHA1_EXE") { - print "ERROR: sha1 executable missing\n"; - exit(1); - } - } - unless (-x $::TSKDIR . "/srch_strings") { - print "ERROR: Sleuth Kit srch_strings executable missing\n"; - exit(1); - } - - if ($::LIVE == 0) { - unless (-x $::TSKDIR . "/sorter") { - print "ERROR: Sleuth Kit sorter executable missing\n"; - exit(1); - } - unless (-x $::TSKDIR . "/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 "$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 $::TSKDIR) && ($::TSKDIR ne "")) { - print "ERROR: TSKDIR variable not set in configuration file\n"; - print " This could been caused by an incomplete installation\n"; - exit(1); - } - - unless (-d "$::TSKDIR") { - print "Invalid Sleuth Kit binary directory: $::TSKDIR\n"; - exit(1); - } - - return if ($::LIVE == 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); - } -} diff --git a/base/make-live-cd.base b/base/make-live-cd.base deleted file mode 100644 index 08c66e9f37..0000000000 --- a/base/make-live-cd.base +++ /dev/null @@ -1,153 +0,0 @@ -# -# This makes a directory ($CD) with the needed files to burn to -# a CD for live analysis -# -# Current limitations are that Perl needs to be on the suspect system and -# that it uses the untrusted Perl files. - -require 'conf.pl'; -use vars '$USE_STIMEOUT', '$STIMEOUT', '$CTIMEOUT', '$SAVE_COOKIE'; -use vars '$GREP_EXE', '$TSKDIR'; - - -my $CD = "./live-cd/"; - -# Make the directories -if (-d "$CD") { - print "Live CD directory already exists ($CD)\n"; - print "Plese delete and run this again\n"; - exit (1); -} - -print "Making base directory ($CD)\n"; -die "Error making Live CD directory ($CD)" - unless (mkdir "$CD", 0775); - -die "Error making Live CD binaries directory ($CD)" - unless (mkdir "$CD/bin/", 0775); - - -print "Copying executables\n"; - -# Copy the executables -die "Missing grep executable ($GREP_EXE)" - unless (-x "$GREP_EXE"); -`cp '$GREP_EXE' '$CD/bin/grep'`; -die "Error copying grep executable" - unless (-x "$CD/bin/grep"); - - -die "Missing MD5 executable ($::MD5_EXE)" - unless (-x "$::MD5_EXE"); -`cp '$::MD5_EXE' '$CD/bin/md5sum'`; -die "Error copying MD5 executable" - unless (-x "$CD/bin/md5sum"); - -# Sleuth Kit Binaries -die "Missing Sleuth Kit Directory ($TSKDIR)" - unless (-d "$TSKDIR"); - -foreach my $exec ("blkcalc", "blkcat", "blkls", "blkstat", "ffind", "fls", "fsstat", - "icat", "ifind", "ils", "istat", "srch_strings", "img_stat", "mmls") { - - die "Missing Sleuth Kit executable ($exec)" - unless (-x "$TSKDIR/$exec"); - - `cp '$TSKDIR/$exec' '$CD/bin/$exec'`; - - die "Error copying Sleuth Kit executable ($exec)" - unless (-x "$CD/bin/$exec"); -} - - -# Make a fake file -open FILE, ">$CD/bin/file" or die ("Error creating Live CD file exec"); -print FILE "#!./bin/perl\n"; -print FILE "print STDOUT \"File Type Not Supported During Live Analysis\n\";\n"; -close FILE; -`chmod +x "$CD/bin/file"`; - - -# Copy the autopsy directories -print "Copying autopsy files\n"; -`cp -r help "$CD"`; -`cp -r lib "$CD"`; -`cp -r pict "$CD"`; - - -# Get the path for Perl from the current autopsy -open AUT, "<./autopsy" or die ("Error opening normal autopsy exec"); -my $perl; -while () { - $perl = $_; - last; -} -close AUT; - -if ($perl =~ /^#!(\S+)/) { - $perl = $1; -} else { - die "Error parsing Perl location from autopsy" -} - - -# Copy the perl exec -# @@@ I'm not sure if just copying the bin is enough ... -die "Missing Perl executable ($perl)" - unless (-x "$perl"); - -`cp '$perl' '$CD/bin/perl'`; - -die "Error copying perl executable" - unless (-x "$CD/bin/perl"); - - -# Make a new autopsy -open AUT, ">$CD/autopsy" or die ("Error opening Live CD autopsy exec"); - -print AUT "#!./bin/perl -wT\n"; -print AUT "use lib '.';\n"; -print AUT "use lib './lib/';\n"; - - -open BASE, "<./base/autopsy.base" or die ("Error opening base autopsy"); - -print AUT $_ - while (); - -close (AUT); -close (BASE); - -`chmod +x "$CD/autopsy"`; - - -print "Creating configuration file using existing settings\n"; - -# Make the configuration file -open CONF, ">$CD/conf.pl" or die ("Error opening Live CD Config file"); - -print CONF "# Configuration file for Live CD version of Autopsy\n"; -print CONF "# http://www.sleuthkit.org/autopsy\n"; -print CONF "# Created on ".localtime()."\n\n"; - -# Variables -print CONF "\$USE_STIMEOUT = $USE_STIMEOUT;\n"; -print CONF "\$STIMEOUT = $STIMEOUT;\n"; -print CONF "\$CTIMEOUT = $CTIMEOUT;\n"; -print CONF "\$SAVE_COOKIE = $SAVE_COOKIE;\n"; - -print CONF "\n"; -print CONF "\$INSTALLDIR = './';\n"; -print CONF "\$NSRLDB = '';\n"; -print CONF "\$LOCKDIR = './read-only-live-version/';\n"; - -print CONF "\n"; -print CONF "# System Utilities\n"; -print CONF "\$GREP_EXE = './bin/grep';\n"; -print CONF "\$FILE_EXE = './bin/file';\n"; -print CONF "\$MD5_EXE = './bin/md5sum';\n"; -print CONF "\$TSKDIR = './bin/';\n"; - -close CONF; - -print "\n"; diff --git a/configure b/configure deleted file mode 100755 index 72d5c84f00..0000000000 --- a/configure +++ /dev/null @@ -1,475 +0,0 @@ -#!/bin/sh - -# Minimum version of TSK that is required -minver="3.1.0"; - -# The last released version of TSK -curtskver="3.1.1"; - -# Configuration script for the Autopsy Forensic Browser -# -# Brian Carrier [carrier@sleuthkit.org] -# -# Copyright (c) 2003-2008 by Brian Carrier. All rights reserved -# -# Copyright (c) 2001-2003 by Brian Carrier, @stake. All rights reserved -# -# 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 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. - - -# Directories to search in -dirs='/usr/local/bin/ /usr/bin/ /usr/ccs/bin/ /bin/ /usr/ucb/bin/ /sbin/ /usr/sbin/ /usr/local/sbin/' - - -echo "" -echo " Autopsy Forensic Browser Installation" -echo "" - - - -############################################################################# -# create conf.pl -############################################################################# - - -conf='conf.pl' - -rep="" -if (test -f $conf) then - echo "A configuration file already exists, overwrite? (y/n):"; - read rep; -else - rep="y" -fi - -if (test "$rep" = "y") then - - -# First add the variables that are static -# -# DEFAULT USER SETTINGS -# -echo '# Autopsy configuration settings' > $conf -echo '' >> $conf -echo '# when set to 1, the server will stop after it receives no' >> $conf -echo '# connections for STIMEOUT seconds. ' >> $conf -echo '$USE_STIMEOUT = 0;' >> $conf -echo '$STIMEOUT = 3600;'>> $conf - -echo '' >> $conf -echo '# number of seconds that child waits for input from client' >> $conf -echo '$CTIMEOUT = 15;' >> $conf - -echo '' >> $conf -echo '# set to 1 to save the cookie value in a file (for scripting)' >> $conf -echo '$SAVE_COOKIE = 1;' >> $conf - - -############################################################################# -# INSTALLATION DIRECTORY -############################################################################# -echo '' >> $conf; -echo \$INSTALLDIR = \'$PWD/\'\; >> $conf; - - -# Now add the variables that need user interaction - -# -# FIND THE UTILITIES -# -echo '' >> $conf -echo '' >> $conf -echo '# System Utilities' >> $conf - - - -# -# GREP -# -echo '' -echo '---------------------------------------------------------------' -echo '' -found=0 -for d in $dirs - do if (test -x ${d}grep) then - echo \$GREP_EXE = \'${d}grep\'\; >> $conf; - echo "grep found: ${d}grep"; - grepexe="${d}grep"; - found=1; - break; - fi; -done - -# Prompt if not found -if (test $found -eq 0) then - echo 'ERROR: grep utility not found'; - echo 'Enter location of executable:'; - while (test 1 -eq 1) - do read grepexe; - if (test -x "$grepexe") then - echo \$GREP_EXE = \'$grepexe\'\; >> $conf; - break; - else - echo 'grep was not found (try again):'; - fi; - done -fi - - -# -# FILE -# -found=0 -for d in $dirs - do if (test -x ${d}file) then - echo \$FILE_EXE = \'${d}file\'\; >> $conf; - echo "file found: ${d}file"; - found=1; - break; - fi; -done - -# Prompt if not found -if (test $found -eq 0) then - echo 'ERROR: file utility not found'; - echo 'Enter location of executable:'; - while (test 1 -eq 1) - do read fileexe; - if (test -x "$fileexe") then - echo \$FILE_EXE = \'$filexe\'\; >> $conf; - break; - else - echo 'file was not found (try again):'; - fi; - done -fi - -# -# MD5 -# -found=0 -for d in $dirs - do if (test -x ${d}md5) then - echo \$MD5_EXE = \'${d}md5\'\; >> $conf; - echo "md5 found: ${d}md5"; - found=1; - break; - elif (test -x ${d}md5sum) then - echo \$MD5_EXE = \'${d}md5sum\'\; >> $conf; - echo "md5 found: ${d}md5sum"; - found=1; - break; - fi; -done - -# Prompt if not found -if (test $found -eq 0) then - echo 'ERROR: md5/md5sum utility not found'; - echo 'Enter location of executable:'; - while (test 1 -eq 1) - do read md5exe; - if (test -x "$md5exe") then - echo \$MD5_EXE = \'$md5exe\'\; >> $conf; - break; - else - echo 'md5 was not found (try again):'; - fi; - done -fi - - -# -# SHA-1 -# -found=0 -for d in $dirs - do if (test -x ${d}sha15) then - echo \$SHA1_EXE = \'${d}sha\'\; >> $conf; - echo "sha1 found: ${d}sha1"; - found=1; - break; - elif (test -x ${d}sha1sum) then - echo \$SHA1_EXE = \'${d}sha1sum\'\; >> $conf; - echo "sha1 found: ${d}sha1sum"; - found=1; - break; - fi; -done - -if (test $found -eq 0) then - echo 'WARNING: sha1/sha1sum utility not found'; - echo \$SHA1_EXE = \'\'\; >> $conf; -fi; - - - -############################################################################# -# The Sleuth Kit -############################################################################# - -echo '' >> $conf -echo '' >> $conf -echo '# Directories' >> $conf - -echo '' -echo '---------------------------------------------------------------' -echo '' -echo 'Searching for Sleuth Kit Installation.' -found=0 -for d in $dirs - do if ((test -x ${d}fls) && (test -x ${d}ffind) && (test -x ${d}blkstat) && \ - (test -x ${d}blkls) && (test -x ${d}blkcat) && \ - (test -x ${d}mmls) && (test -x ${d}mmstat) && \ - (test -x ${d}fsstat) && (test -x ${d}img_stat) && \ - (test -x ${d}istat) && (test -x ${d}ifind) && \ - (test -x ${d}icat) && (test -x ${d}ils) && \ - (test -x ${d}srch_strings) && \ - (test -x ${d}mactime) && (test -x ${d}sorter)) then - echo \$TSKDIR = \'${d}\'\; >> $conf; - tskdir=${d}; - echo "Found in: ${d}"; - found=1; - break; - fi; -done - -if (test $found -eq 0) then - echo 'Sleuth Kit tools were not found in the standard install locations.' - echo 'If you have not installed them, do so now and configure autopsy again.' - echo 'If you have installed them in a non-standard location, then' - echo ' enter the "bin" directory now:' - - while (test 1 -eq 1) - do read tskdir; - if ((test -x ${tskdir}/fls) && (test -x ${tskdir}/ffind) && (test -x ${tskdir}/blkstat) && \ - (test -x ${tskdir}/blkls) && (test -x ${tskdir}/blkcat) && \ - (test -x ${tskdir}/mmls) && (test -x ${tskdir}/mmstat) && \ - (test -x ${tskdir}/fsstat) && (test -x ${tskdir}/img_stat) && \ - (test -x ${tskdir}/istat) && (test -x ${tskdir}/ifind) && \ - (test -x ${tskdir}/icat) && (test -x ${tskdir}/ils) && \ - (test -x ${tskdir}/srch_strings) && \ - (test -x ${tskdir}/mactime) && (test -x ${tskdir}/sorter)) then - echo \$TSKDIR = \'${tskdir}\'\; >> $conf; - break; - else - echo 'TSK tools were not found or incomplete (try again):'; - fi; - done -fi; - -# Test for latest version -ver=`"${tskdir}/fls" -V | awk '/The Sleuth Kit ver / {print $5}'`; -echo " Version $ver found"; - - -if (test "$ver" '<' "$minver") then - echo "Your version of The Sleuth Kit is not current enough - $minver is needed"; - if (test "$ver" '>' "0.0.0") then - exit 1; - fi; -elif (test "$ver" '<' "$curtskver") then - echo ''; - echo "*** NOTE: A more recent version ($curtskver) of The Sleuth Kit Exists ***" - echo " [Press Enter to Continue]"; - read foo; - -else - echo ' Required version found'; -fi - - - -# NSRL -echo '' -echo '---------------------------------------------------------------' -echo '' -echo 'The NIST National Software Reference Library (NSRL) contains' -echo 'hash values of known good and bad files.' -echo ' http://www.nsrl.nist.gov' -echo '' -echo 'Have you purchased or downloaded a copy of the NSRL (y/n) [n]' -read rep; -if (test "$rep" = "y") then - - echo 'Enter the directory where you installed it:' - while (test 1 -eq 1) - do read nsrldir; - if (test "$nsrldir" = "cancel") then - echo \$NSRLDB = \'\'\; >> $conf; - break; - fi; - if (test -f "${nsrldir}/NSRLFile.txt") then - echo ' NSRL database was found (NSRLFile.txt)'; - echo \$NSRLDB = \'${nsrldir}/NSRLFile.txt\'\; >> $conf; - - if (test -f "${nsrldir}/NSRLFile.txt-md5.idx") then - echo ' NSRL Index file found (NSRLFile.txt-md5.idx)'; - else - echo ' NSRL Index file not found, do you want it created? (y/n) [n]:' - read rep; - if (test "$rep" = "y") then - echo '' - echo '-------------- begin hfind output --------------' - "${tskdir}/hfind" -i nsrl-md5 "${nsrldir}/NSRLFile.txt"; - echo '--------------- end hfind output ---------------' - echo '' - fi; - fi; - break; - else - echo 'The NSRL was not found (the directory should have NSRLFile.txt in it)'; - echo 'Enter a new directory (or cancel to stop):'; - fi; - done -else - echo \$NSRLDB = \'\'\; >> $conf; -fi; - -############################################################################# -# EVIDENCE LOCKER -############################################################################# -mdone=0 -echo '' -echo '---------------------------------------------------------------' -echo '' -echo 'Autopsy saves configuration files, audit logs, and output to the' -echo 'Evidence Locker directory.' -echo '' -echo 'Enter the directory that you want to use for the Evidence Locker:'; -read locker; -if (test -d "${locker}") then - echo " $locker already exists" -else - echo ''; - echo "WARNING: $locker does not exist" - mdone=1 -fi - -echo \$LOCKDIR = \'${locker}\'\; >> $conf; - -fi - -# Start of non-conf.pl file configuration - -############################################################################# -# Setup Perl locations -############################################################################# -found=0; - -for d in $dirs - do if (test -x ${d}perl) then - if (test -n "`${d}perl -v 2> /dev/null | awk '/This is perl/ {print $0}'`") then - ver=`${d}perl -e 'print $];'`; - if (`${d}perl -e 'exit( $] >= 5.008);'`) then - echo "old version of perl found: ${d}perl (version $ver) -- continuing"; - else - echo "perl found: ${d}perl (version $ver)"; - echo "#!${d}perl -wT" > ./config.tmp; - echo "#!${d}perl" > ./config2.tmp; - perlexe="${d}perl"; - found=1; - break; - fi; - fi; - fi; -done - -# If it wasn't found, then prompt for it. -if (test $found -eq 0) then - echo 'ERROR: perl not found or the incorrect version found'; - while (test 1 -eq 1) - do echo 'Enter location of perl executable:'; - read perlexe; - if (test -x "$perlexe") then - if (test -n "`$perlexe -v 2> /dev/null | awk '/This is perl/ {print $0}'`") then - ver=`$perlexe -e 'print $];'`; - if (`$perlexe -e 'exit( $] >= 5.008);'`) then - echo "This version of Perl is too old, 5.8.0 or older needed"; - else - echo "Correct version found"; - echo "#!${perlexe} -wT" > ./config.tmp; - echo "#!${perlexe}" > ./config2.tmp; - found=1; - break; - fi; - else - echo "Perl found, but is not working. Try another"; - fi; - else - echo "file not found"; - fi - done -fi - -# Check if this version of Perl supports large files -if (test -z "`$perlexe -V 2> /dev/null | awk '/USE_LARGE_FILES/ {print $0}'`") then - echo '' - echo ' NOTE: It appears that your Perl does not support large files.'; - echo ' You therefore will not be able to analyze images larger than 2GB.'; - echo ' Download the source version from www.cpan.org and compile a new version.'; - echo " [Press Enter to Continue]"; - read foo; - echo '' -fi; - -# Get current working directory for lib -echo "use lib '$PWD/';" >> ./config.tmp -echo "use lib '$PWD/lib/';" >> ./config.tmp - -if (test -f ./autopsy) then - echo "autopsy already exists, overwrite? (y/n):"; - read rep; - if (test "$rep" = "y") then - cat ./config.tmp base/autopsy.base > ./autopsy - cat ./config2.tmp base/make-live-cd.base > ./make-live-cd - else - echo ' original version was kept'; - fi -else - cat ./config.tmp base/autopsy.base > ./autopsy - cat ./config2.tmp base/make-live-cd.base > ./make-live-cd -fi -chmod 0755 ./autopsy -chmod 0755 ./make-live-cd - -# cleanup -rm -f ./config.tmp -rm -f ./config2.tmp - - -############################################################################# -# CLEANUP -############################################################################# -echo '' -echo '---------------------------------------------------------------' -echo '' -echo "Execute the './autopsy' command to start with default settings." -echo '' - diff --git a/docs/sleuthkit-informer-13.txt b/docs/sleuthkit-informer-13.txt deleted file mode 100644 index 24d55bb371..0000000000 --- a/docs/sleuthkit-informer-13.txt +++ /dev/null @@ -1,410 +0,0 @@ - The Sleuth Kit Informer - - http://www.sleuthkit.org/informer - http://sleuthkit.sourceforge.net/informer - - Brian Carrier - carrier at sleuthkit dot org - - Issue #13 - March 15, 2004 - - - -CONTENTS --------------------------------------------------------------------- -- Introduction -- What's New? -- Call For Papers -- Did You Know? -- UNIX Incident Verification With Autopsy - - - -INTRODUCTION --------------------------------------------------------------------- - -I'm almost done! Releasing version 2.00 of Autopsy that is. I'm -polishing up the final changes and documentation and it will be -released later this week. March 19 is the birthday of Autopsy and -The Sleuth Kit's predecessor, TCTutils, also the goal release date -for version 2.00. - -This issue of the Informer will focus on the new live analysis -feature of (the unreleased) Autopsy. This issue also has a lot -entries in the "What's New?" category because we are on a bimonthly -schedule. If you missed getting the February issue of The Informer -and have lessons to share with people then make sure you read the -Call For Papers section so that you can learn how to submit articles -of your own. - - - -WHAT'S NEW? --------------------------------------------------------------------- -A new version (1.68) of The Sleuth Kit was released. It contains -a couple of bug fixes. There have been discussions on the -sleuthkit-developers list about what new functions should be added -to the next big version 2.00 release. Michael Cohen has been looking -into support for disk images, split images, RAID images, and other -non-raw formats. David Collett has been looking into output formats -for TSK tools so that they can be imported into databases. - -Version 2.00 of Autopsy will be released later this week. I'm -adding the final touches and documentation and the goal is to release -it on March 19, which is the 3 year anniversary of the first release -of Autopsy and TCTutils. Version 2.00 has a new internal design -and has live analysis features (see below article). If you can't -wait for a few days and want one of the beta copies, let me know. - -Guido Metzner has been translating The Sleuth Kit Informer into -German. If anyone else is translating this, let me know and I'll -add a link. - - http://www.guframe.de/sleuthkit.html - - -I started to provide a GPG signature of the source code as it is -released. I have meant to do this for ages. This can help to -ensure that the code being downloaded has not been modified by an -attacker. - - - -CALL FOR PAPERS --------------------------------------------------------------------- - -I posted a call for papers on the website in late January for -people that are interested in writing articles for the Informer. -Here is the relevant section: - -The Sleuth Kit Informer is looking for articles on open source tools -and techniques for digital investigations (computer / digital -forensics) and incident response. Articles that discuss The Sleuth -Kit and Autopsy are appreciated, but not required. Example topics -include (but are not limited to): - -- Tutorials on open source tools -- User experiences and reviews of open source tools -- New investigation techniques using open source tools -- Open source tool testing results - -http://www.sleuthkit.org/informer/cfp.html - - -Writing these articles takes away from my development time of new -tool features, so any help is appreciated. To keep with the incident -verification theme, any articles on the basics of using 'netstat', -'lsof', etc. to look for signs of an intrusion are also welcome for -the next few issues. If we get enough interest, I'll consider going -back to a monthly schedule. - - - -DID YOU KNOW? --------------------------------------------------------------------- - -Have you ever noticed that the number of occurrences and locations -of keywords for regular expressions in Autopsy are not always -accurate? This came up on one of the mailing lists this past month -and I'll explain it again here. - -Previous issues of The Informer have covered keyword searching, but -the general idea in Autopsy is that it runs the 'strings' command -on the image file and then uses 'grep' to find the keyword. The -'strings' command returns a long ASCII string that grep examines. -If the keyword is found in the string, then grep fill flag the -string and autopsy will search the string to find the exact location -of the keyword. - -This is easy if a non-regular expression is used, but much more -difficult with regular expressions because 'grep' regular expressions -are different from Perl regular expressions. I do not have a way -to convert the grep regular expression to Perl and therefore I only -return the number of big strings that have the keyword and the -location of the start of the big string. There could be more than -one keyword in the string, in which case the total occurrences value -is too small. The location will also be off because it points to -the start of the large string and not the specific keyword. - -If anyone knows of, or wants to write, a grep to perl regular -expression converter, let me know so that we can update this. - - - -UNIX INCIDENT VERIFICATION WITH AUTOPSY --------------------------------------------------------------------- - -INTRODUCTION - -For a couple of years, I have been saying that Autopsy can be used -to analyze a live system, but it has taken me a while to make it -EASY to use to analyze a live system. When version 2.0 of Autopsy -is released later this week, you will find that it is much easier -to configure so that it runs on a CD-ROM so that you can examine a -system that is suspected of being compromised. This will allow you -to view files that are hidden by rootkits and will not change the -access times on files that are viewed. - -This article will give an overview of how to use the new features -and what features are available for dead analysis are not for live -analysis. I will also show the future work for Autopsy. This -article uses many of the same concepts as the "UNIX Incident -Verification with The Sleuth Kit" article in issue #10 of the -Informer. - -MOTIVATION - -Some may be asking "why would I want a live analysis feature?". -The primary motivation is for a more automated Incident Verification -procedure. We saw in issue #10 of the Informer, that The Sleuth -Kit can be used to verify an incident because it can show files -that are hidden by rootkits and will not update the access times -on files when they are read. Executing a bunch of command line -tools is tedious though and Autopsy can provide a more automated -investigation procedure. - -The basic scenario is that Autopsy and The Sleuth Kit will be burned -to a CD and inserted into a suspect computer. An investigator will -connect to Autopsy on the suspect UNIX computer with her HTML browser -on a trusted laptop and remotely examine the hard disk contents. -If the computer is found to have been compromised, then it can be -taken offline and acquired using normal procedures. - -Recall from issue #10 that I used two guidelines for incident -verification: - - 1. Minimize the amount of trust that you place in the system so - that more accurate information is collected. - - 2. Minimize the amount of data that you change on the system so - that evidence is preserved. - - -CREATING THE CD - -To satisfy guideline #1 from above, we want to minimize the amount -of trust that we place in the system, so we use our own executables. -At a minimum, we need The Sleuth Kit and Autopsy on the CD and you -will probably have additional tools to examine open network ports -and running processes. This has been the most difficult part of -using Autopsy for live analysis because Autopsy relies on a given -directory structure and locations that it can write to. - -It is now very easy with v2. With v2, you compile TSK and Autopsy -on a similar system to the one that will be investigated just like -you do for a dead analysis. Try the 'make static' with TSK to see -if you can make static executables for your platform. After both -Autopsy and TSK have been compiled, you execute the 'make-live-cd' -command in Autopsy. This script will make a 'live-cd' sub-directory -in the autopsy directory, which contains a copy of autopsy and -copies of TSK executables, grep, strings, perl etc: - - # ./make-live-cd - Making base directory (./live-cd/) - Copying executables - Copying autopsy files - Creating configuration file using existing settings - - -The 'live-cd' directory has a 'bin' directory where additional -executables can be copied to and then the whole directory can be -burned to a CD. - - -BASIC USAGE - -After the CD has been created and there is a system suspected of -being compromised, then it is time to take advantage of the new -features. There are two scenarios for live analysis. The first -scenario uses a network share from a trusted system that you can -write to. In this case, autopsy is run as normal and you specify -the evidence locker directory as the mounted disk. The evidence -locker is specified with '-d': - - # ./autopsy -d /mnt/ev_lock 10.1.32.123 - -The above would start autopsy, use '/mnt/ev_lock/' as the evidence -locker and would allow connections from 10.1.32.123 (where the -investigator would connect from using an HTML browser). Remember that -we do not want to write to the suspect system, so we should only use -a network share and not a local directory in this scenario. - -The second scenario does not use an evidence locker and does not -intentionally write any data to disk. This scenario does not need -the network share and each of the devices (or partitions) that will -be analyzed are specified on the command line using the '-i' flags. -The '-i' flag requires three arguments: the device, the file system -type, and the mounting point. For example, to examine the '/dev/hda5' -and '/dev/hda8' partitions on a Linux system, the following could -be used: - - # ./autopsy -i /dev/hda5 linux-ext3 / -i /dev/hda8 linux-ext3 /usr/ \ - 10.1.32.123 - -The file system type must be one of the types that are supported -by TSK. The remote IP address must also be given, otherwise you -will have to use a browser on the suspect system and that will write -data to the disk. - -When you use the '-i' flag, then autopsy will start in the 'Host -Manager' view where you can select the image that you want to -analyze. You will skip the case and host configuration. The default -case name will be 'live', the default host name is 'local', and the -default investigator name is 'unknown'. - - -DIFFERENCES WITH DEAD ANALYSIS - -There are some features that are not available for live analysis -because they write files to the disk. In this section, I am using -the term live analysis for the scenario where there is not a mounted -network share and there is not evidence locker. - -No auditing is performed during a live analysis because there is -no where to write the logs. In the future, if this is needed, then -a method of writing logs to a floppy disk could be configured. -Timelines of file activity cannot be created because they need to -create files. Hash databases are also not currently used, although -they could in the future. It may be difficult to maintain the -latest hash database on the same CD as the latest autopsy and TSK -version though. Notes and event sequencer notes cannot be created. - -Keyword searches can be performed, but the strings file and unallocated -only search cannot be performed because they both require a file -to be created. The search results are also not cached. You can -also not sort files by their type (all executables, all pictures -etc.). In many cases, you would not want to do many of these -operations because they are time intensive and you are generally -looking for obvious and quick evidence during the incident verification. -If you need theses features, then you can use the network share -scenario. - - -SIMILARITIES WITH DEAD ANALYSIS - -Now that we know what is different, I'll cover what is the same. -All of the file mode analysis is the same, except that you cannot -get the file type. The method that is used to compile 'file' in -TSK does not allow autopsy to easily move it around. This behavior -may change in the future. Meta data, data unit, and file system -mode all work as usual. - -You can still export file contents to your trusted laptop because -it uses the HTTP to save the file. So, you can select the export -button on a log file to save a copy. You can also generate ASCII -reports and save them to your local analysis station. - - -GUIDELINE COMPLIANCE - -All of these features may sound great, but lets examine how well -the new Autopsy satisfies the two guidelines. I think it is always -important to compare a new tool or technique against generic -guidelines. - -The first guideline was about not trusting the local system. No -software-based live analysis tool can be 100% independent from the -local system because it always needs to request service from the -operating system. With Autopsy, we use our own copies of the Autopsy -perl code, TSK executables, grep, and strings. - -There is one large problem with the current Autopsy model and it -is because of Perl. Perl is a beast and contains many modules and -libraries. When the 'make-live-cd' script is run, a copy of the -'perl' executable is copied to the 'live-cd' directory, but that -is it. The executable will still need the modules and libraries -on the local system. Solving this may require building a special -version of Perl that is more static. I need to investigate this -more. - -Another method of getting around this limitation is to use the -'perl2exe' program that converts a Perl script to a dynamic executable. -The resulting executable will still rely on dynamic libraries on -the suspect system, but it seems a little cleaner. The perl2exe -program is a commercial tool. - -One of the benefits of the Autopsy design, is that Autopsy did not -exist on the system when it was suspected of being compromised. -Therefore, the attacker will not know that Autopsy will be used to -investigate the system and therefore will be less likely to tamper -with its dependencies. If the investigation tools are running on -the system during the attack, then I would guess that the attacker -will be more likely to tamper with them. - -The second guideline was about modifying data on the system. I -described the features that were removed in the previous section. -This was easy to do because there were functions that write the -logs or notes. Each of those starts with a check to see if logging -is enabled. Timelines and file type sorting were also disabled -because it required writing to disk. - -I can never guarantee that no data will be written from a live -analysis. Memory will be overwritten when the software is loaded -and the access times on dynamic libraries will updated. Running -the tools may require the operating system to write memory to the -page file, which may overwrite data from the attacker. - -This is a shameless plug, but for those that are interested in live -analysis, then you may want to check out a paper that a colleague, -Joe Grand (author of pdd), and I wrote about a hardware device to -acquire memory from a live system. It does not overwrite memory -because there is no process to load and it access the physical -memory directly so it does not rely on the local operating system. -It was recently published in the new Journal of Digital Investigation -(reference is below and that issue of the journal is currently free -to view). - - - -FUTURE WORK - -There is always more to do, and I'll cover that here. - -I would like to also include other system utilities, such as 'ps' or -'netstat' on the CD and allow the Autopsy user to run the commands -from within autopsy. This should be fairly easy, but the difficult -part is that many of the operating systems use different flags for -different tools. - -I would like to start incorporating scripts into the tool (for both dead -and live analysis). This will allow you to more easily detect rootkits -or other signatures. - -The biggest thing that needs future work is using Perl. Autopsy -still relies on the version of Perl on the suspect system and that -could run into problems if an attacker modifies it. Using the -perl2exe tool can reduce the risk, but it is a commercial tool. - - -CONCLUSION - -The live analysis mode of Autopsy allows you to more easily analyze -a system that is suspected of being compromised. It can also be -used to examine a honeypot. Live analysis is not ideal because you -are stilly relying on the suspect operating system for data, but -it is required in some situations. More work needs to be done with -Autopsy so that it depends less on the local system. - - - -REFERENCES -Autopsy - http://www.sleuthkit.org/autopsy/ - -perl2exe - http://www.indigostar.com/perl2exe.htm - -Sleuth Kit - http://www.sleuthkit.org/sleuthkit - -Sleuth Kit Informer #10 - http://www.sleuthkit.org/informer/sleuthkit-informer-10.html - -A hardware-based memory acquisition procedure for digital investigations - Brian D. Carrier and Joe Grand - Volume 1, Issue 1 - Journal of Digital Investigations - http://www.sciencedirect.com/science/journal/17422876 - --------------------------------------------------------------------- -Copyright (c) 2004 by Brian Carrier. All Rights Reserved diff --git a/global.css b/global.css deleted file mode 100644 index d44dcca673..0000000000 --- a/global.css +++ /dev/null @@ -1,19 +0,0 @@ -h3 { - font-size: 18px; - color: #000000; -} -h2 { - font-size: 20px; - color: #000000; -} -h1 { - font-size: 24px; - color: #000000; -} -body { - font-family: Helvetica, Geneva, Arial, sans-serif; - font-size: 14px; - color: #000000; - #background-color: #dedede; -} - diff --git a/help/blank.html b/help/blank.html deleted file mode 100644 index 3e40eb24cf..0000000000 --- a/help/blank.html +++ /dev/null @@ -1,25 +0,0 @@ - -Blank Page - -   -

-   -

-   -

-

-

HELP!

- Here are the help files for using Autopsy. - -

In addition to these files, the Sleuth Kit Informer - newsletter could be useful.
- The Informer typically goes into more technical details than what - is provided here.

- -

- http://www.sleuthkit.org/informer/

- -

Send documentation updates to <doc-updates at sleuthkit dot org>

- - - diff --git a/help/caseman.html b/help/caseman.html deleted file mode 100644 index ee4fc315b8..0000000000 --- a/help/caseman.html +++ /dev/null @@ -1,161 +0,0 @@ - -Autopsy Case Management Help - - - -

Case Management

-

-

Overview

-Autopsy organizes images based on the case and host that they came -from. A case contains one or more hosts (a new case should be -created for each investigation). Each host can contain one or more -images, which correspond to disks or partitions on the host. - - -

-

Creating a New Case

-From the Main Menu (at startup) select New Case. You will -have to enter the case name and an optional short description. -The case name must be a valid directory name (no spaces - no -symbols). A list of investigators will also be requested. These -will be used for the audit logs, not for authentication. A directory -with the same name as the case will be created in the Evidence -Locker. To later rename the case, simply rename the directory. - -

-For example: - - - - - - - - - - -
Case Name:bankofmars
Case Description:Theft of $1,000,000,000.01 from The Bank of Mars
Investigators:gadget
- -

-

Adding a New Host

-A Host must then be created in the Case. Select the Case that was -just created from the Case Gallery and enter the Host Gallery. -Select Add Host and enter the host name, a short description, -and time information such as time zone and clock skew. The clock -skew is how many seconds the system was off from a synchronized -clock. Adding a host will create a directory in the case directory -and subdirectories in the host for the images, output data, logs, -and reports. If you do not add a time zone, then it will default to -the time zone of your analysis system. A list of time zones can be -found here. - -

-You can optionally add the path to hash databases. - -

-For example, the 'Bank of Mars' incident could have two hosts -involved: - - - - - - - - - - - - - - - - - - - - -
Host Name:db_server
Host Description:Main Database Server - Solaris
Timezone:EST5EDT
Timeskew:-100
Known Good Database:none
Known Bad Database:none
- -

- - - - - - - - - - - - - - - - - - - -
Host Name:file_server
Host Description:Windows File Server - Win 2k
Timezone:CST6CDT
Timeskew:0
Known Good Database:/usr/local/forensics/hash/win2k.txt
Known Bad Database:/usr/local/forensics/hash/win_hack.txt
- -

-

Adding a New Image

-Next, images must be added to the host. Select the host that was -just added from the Host Gallery and enter the Host Manager. Select -Add Image File and a new form is shown. The first text box in -the form is for the path of the image file. If you are importing a -split image, then the extension must be ordered based on the file order. -Supply a '*' in the file name extension where the numbers or letters are. -(i.e. .../image.*). The image file can be -of a full disk or of an individual partition. You must select which -it is though. Before they can analyzed, the images will have to -be located in the evidence locker. You are given a choice to either -create a symbolic link from the current location, to copy the file, -or to move the file from its current location to the host directory. -Select the desired import method. For example: - - - - - -
Image Path:/mnt/sys1/disk2.*
Type:Disk
Import Action:symlink
- -

-If you are importing a split image, then the next window will confirm the -order of the images. After that, the next window will allow you to specify -or calculate the MD5 for the file. This should be of the full file and if you -are importing a split image then it should be for all files combined. -If you are importing a volume image, then Autopsy will try to determine the -file system type. You will also need to specify the mounting point. This is used for cosmetic purposes only when printing the full path of files. - -

-If the image file is a disk image then Autopsy will list all of the partitions and try to determine the file system in each one. You have the option to not import a partition and to change the file system type. - -

-

MD5 Values

-Each host has an md5.txt file that contains -the MD5 value for files in that directory. Autopsy uses that file -to validate the integrity of files. By default, when a file is -imported into Autopsy, its MD5 will be calculated. If it is already -known, then it can be entered in the 'Add Images' window. - - -

-

Host Subdirectories

-Each host has an images directory and an output -directory. All data generated by Autopsy is saved to the output -directory. The theory behind this design, was to allow the images -directory to have strict permissions to prevent accidently modifying -the images. Therefore, the images directory can have its write -bits removed to prevent modifications. - -

-

References

-Issue 2 of The Sleuth Kit Informer discusses case management and how to break a disk image into file system images. - - - -


-Brian Carrier - diff --git a/help/data_mode.html b/help/data_mode.html deleted file mode 100644 index db2d20eafd..0000000000 --- a/help/data_mode.html +++ /dev/null @@ -1,97 +0,0 @@ - -Autopsy Data Unit Analysis Help - -

Data Unit Analysis

- - -

Overview

-

-The Data Analysis Mode allows an investigator to view the contents -of an individual data unit. Data units is a generic term used to -describe the areas on the disk that are used to store data. Each -file system calls the data unit a different thing (i.e. Fragments -or Clusters). This mode is most useful when recovering and analyzing -deleted data. - -

Input

-

-To view the contents of a specific address, enter it into the text -box on the left-hand side. By default, only one data unit will be -displayed. To view more than one consecutive unit, enter the -number in the text box below. - -

-It is common to extract the unallocated space from a file system -image and analyze it for deleted material. The 'blkls' tool in The -Sleuth Kit allows one to extract the data. If interesting data is -found in the 'blkls' file, the next step could be to find its location -in the original image and examine the surrounding data. To do -this, simply calculate which data unit the data was found in (by -dividing the byte offset of the interesting data by the data unit -size (which can be found in Image Details)). Enter that -address into the original text box and select the Unallocated -type. This will find the original location and display it for you. - -

-If Autopsy knows about the 'blkls' image, then it can be loaded at any -time by selecting the Load Unallocated button. Then, any -data unit in that file can be examined. - - -

-The Lazarus tool was part of TCT. It analyzes a chunk -of data and identifies what file type it is and tries to group -consecutive types together. Lazarus numbers its output though starting -with 1. Therefore, instead of subtracting 1 every time you want to view -a data unit identified by Lazarus, simply select the check box. - -

-Press the Ok button to display the contents of the address on -the right-hand side of the window. - -

-The Allocation List link displays the allocation status of -addresses in intervals of 500. - - -

Viewing

-

-After the unit address has been entered, the contents are displayed -in the right-hand side. Filters can be used to view the data in the -desired format (strings, hexdump, ASCII). - -

-A report can be generated so that the contents and meta-data about -it will be saved on record. To save the contents locally, press the -Export Contents button. The Add Note button will allow -one to add a comment about the given data unit so that it can be -easily recalled later. - -

-The file type is also displayed. This is identified by running -the output through the 'file' command in The Sleuth Kit. - - - -

-Autopsy will try to find the meta-data structure that allocated -the unit and display both its address and a file name. This process -is very slow for FAT file systems, so this process is not done by -default during analysis. - -

FAT Notes

-

-The Sleuth Kit and Autopsy do not use clusters when dealing with a FAT image. -Only sectors are used. The reason is because FAT does not start -addressing clusters until many sectors into the file system. If -clusters were used to address data units, then there would be no -way to address the sectors in the FAT and secondary FAT. Therefore, -sectors are used for all addresses. NTFS changed the way clusters -were addressed and do not have this problem. See the documentation -in The Sleuth Kit for more details. - - -

-


-Brian Carrier - diff --git a/help/file_category.html b/help/file_category.html deleted file mode 100644 index 6665c90b68..0000000000 --- a/help/file_category.html +++ /dev/null @@ -1,99 +0,0 @@ - -Autopsy File Category Help - - -

File Category Type Analysis Help

- -

Overview

-Analyzing large file system images can be very daunting. One way -of identifying files that should be examined is to sort the files based -on file type. This mode of Autopsy will allow one to sort the files -in an image based on type and to exclude known files (i.e. data -reduction). It also allows one to flag files that are known to be bad. - -

Procedure

-The sorter document in the docs directory of The -Sleuth Kit has more details on the details, but this will provide -an overview of the interface given by Autopsy. - -

-The first step is to Sort the image. There are several -options to choose when doing this. The sorter tool from -The Sleuth Kit will perform the sorting. There are two major -actions that sorter can do: sort files by type and validate -extensions. - -

-By default, Autopsy will perform both actions. If you do not want -it to do a given action, deselect it. - - -

Within sorting, there are two options: - -

    -
  • The first is to save the output. By default, -details about each file will be added to a category file. For -example, a JPEG image will have the meta data address and image -name saved to the images file. By selecting the Save -option, a directory will be created for each category and a copy -of the files will be saved. This could require lots of disk space -(as much as the original image size). - -
  • The second option is to save unknown file types. There are -configuration files that contain rules about common data types. If -a file is encountered that does not have a rule, it is added to an -unknown file. If this is not desired, select the Do Not -Save Unknown option. -
- -

-During the sorting process, the sorter tool will also examine -the extension of the file. If the file type is known, it has known -extensions, and the file does not have one of those extensions, it will -be added to a mismatch file. This can be deselected if it is -not wanted. - - -

Hash Databases

-One easy way of data reduction is to use hash databases. The sorter -tool can use three different hash databases. Each can be configured -within Autopsy and used in other screens. - -
    -
  • NIST NSRL: The NIST NSRL contains hashes of trusted operating - systems and programs. This is used to ignore known files. Files found - in the NSRL will not be included in the file categories (to save time - when reviewing the files). If the file is in the NSRL and has an - extension mismatch, it will be noted in a special file. - -
  • Ignore Database: This database must be created by the user - and added to the host. It is similar to the NSRL in that it contains - hashes of known good files. They will be ignored in the same way that - those from NSRL are. - -
  • Alert Database: This database must also be created by the - user and added to the host. It contains hashes of files that are - known to be bad and should identified if found in the image. This would - include known rootkits or photographs. Hits from this databases are - found in the alert file. -
- -

-More details can be found in the Hash -Database Help. - -

Output

-Currently, there is no way to view the output from within Autopsy. -All data can be found in the output directory of the host. -A directory is created for the sorter output. View the -index.html file and it contains links to the other files. - -

-

References

-Issues 3, 4, and 5 of The -Sleuth Kit Informer discussed using the 'sorter' tool. - - -
-Brian Carrier - diff --git a/help/file_mode.html b/help/file_mode.html deleted file mode 100644 index ca39d1d342..0000000000 --- a/help/file_mode.html +++ /dev/null @@ -1,221 +0,0 @@ - -Autopsy File Analysis Help - - -

File Analysis

-

Overview

-The File Analysis mode allows one to analyze an image from the file -and directory perspective. This provides the same interface that users -typically use with a normal computer. This mode will also display -information about deleted files though. - -

-This mode will allow one to examine the contents of files and directories -for evidence. It even allows one to perform basic binary analysis by -extracting the ASCII strings from a binary file. The files can also -be sorted by any field. - - -

Directory List

-

-The left-hand side window has four main options: -

    -
  • Directory Seek -
  • File Name Search -
  • Hide / Expand Directories -
  • Show All Deleted Files -
- -

-By default, the directory listing is not shown when this mode is -first entered. By select the Expand Directories button, -the full list of directories will be shown. The number of '+' -symbols represent the depth of the directory. As this is an HTML -interface and there is no state management occurring (no cookies -or session id), it would be difficult to have an interface where -one or more directories are expanded yet the rest are collapsed. - -

-Selecting the All Deleted Files link will display all of the deleted -files in the image on the right-hand side. - -

-There is a text box where a directory (or file) name can be -entered and it will be displayed on the right-hand side. This -makes it easy to jump to a directory without going through the -directory listings. For example, to seek to the 'windows\system32' -folder, you can enter that string into the box instead of scrolling -through the directories. - -

-There is also a text box where a pattern of a file name can be -entered and all files that match that pattern will be displayed on -the right-hand side. The search pattern is a Perl regular expression, -so some values, such as '.' or '*' will need to be escaped. The -search is done case insensitive. To find all files that have a JPG -extension, the following could be used "\.jpg". Or to find all files -that begin with a dot, then we could use "^\.". - - -

Directory Contents

-

-The window in the upper right-hand side contains the directory -contents. In a file system, a directory allocates data units on -the disk and fills the data units with structures that contain the -name of the file and the address of the meta data structure. This -view parses the file name structures in the directory. It is filled -by either selecting a directory from the left-hand side directory -list or a directory from within the same window. The entries can -be resorted by clicking on any of the header values. - -

-The column headers have the following definitions: -

    -
  • del: A check in this column represents a deleted file. - See below for a discussion on the different color types of deleted files. - -
  • Type: This column contains the "type" that the file or - directory is. There are two values. The first (dir) is the - type according to the directory entry structure. The directory entry - is where the file name is located. The second value (in) is - the type according to the meta data structure. - These should be the same except - for deleted files. They are both given to help the investigator - identify if a deleted file has been reallocated or not. For example, - if the meta data structure type is different than the file name - type, then it is likely that one of the structures was reallocated for - a new file. - -
  • Name: The name of the file or directory. Clicking on the - name displays file contents in the bottom window or directory contents - in the same window. For deleted files, no link will exist if the meta - data structure address - has been cleared (which many OS do). To identify the destination of - a UNIX symbolic link, - click on the address at the end of the row. Note that the name - will not be a link if the size of the file is 0 or if the meta data - structure is unknown. - -
  • Modified Time: This column exists for UNIX and NTFS file - systems. It shows the last time that the file data was last modified. - In other words, when was data last written to the data units allocated - by the file. In UNIX, the utimes() function can modify this - value vary easily. - -
  • Written Time: This column exists for FAT file systems and - is the time when the file was last written to. Of the three times, - this is the only value that is required by the FAT specification. - -
  • Accessed Time: This column contains the last accessed time of - the file data. On a FAT image, this value is optional and is only - accurate to the day (not hours or seconds). This value can be - modified by the utimes() function in UNIX. - -
  • Changed Time: This column exists for UNIX and NTFS file - systems. It is the last time that the file status (or meta data) was - changed. This is different than the Modified time because modified - deals with the file data and this deals with the descriptive data - in the inode or MFT entry. This value cannot be changed by the - utimes() function in UNIX. - -
  • Created Time: This column exists for NTFS and FAT file systems. It - is the time when the file was created. According to the FAT spec, - it is an optional time. - -
  • Size: The size of the file. Note that if the size of the - file is 0, no link will be shown with the name. - -
  • UID: The User ID of the file owner. - -
  • GID: The Group ID of the file owner. - -
  • Meta Data: The file name structures contain a pointer to - the meta data structure that describes the file. This column contains - the address of the structure. Selecting this value - will display the details in the bottom window. - If the value is invalid, then a link will not exist. If it is for - a deleted file name that has a meta data structure with an allocated - status, a "realloc" string will - exist to identify this. - -
-The Add Note link allows you to make a comment about this directory and -have it saved in your personal notes file. - -

-The Generate MD5 List -link will generate the MD5 value for every file in the directory and -allow you to save it as a text file. Using fingerprint data bases, -This makes it easy to check for files that were modified by an attacker. - -

-The path on top of the window has hyperlinks in it that allow the -user to easily change to a previous directory. - -

-There are two different colors used for deleted files. The difference -is based on the status of the data structures in the file. A bright red entry means that the file -name data structure is not allocated and the meta data structure -that it points to is also not allocated. This is what we would -expect of a recently deleted file. This means that we can trust -the data we are seeing as long as the meta data structure was not -allocated and unallocated since the deletion. If it is darker red, then the meta data -structure has been reallocated and the data is most likely not -accurate. - - -

-The file size reported by the meta data structure is very important -with The Sleuth Kit. The Sleuth Kit uses this value to identify -how many data units to display. If this size is 0, but the meta -data structure points to data blocks still, they will not be shown. -You can force Autopsy to display the values by selecting the meta -data address and using the 'force' option. - -

-To look a file up in one of the Hash -Databases, then select the meta data address. That view will -provide an interface to the databases. - -

File Contents

-

-The lower right-hand side window displays the contents of a specified -file. The contents can be viewed in either the raw format (which your -browser will not likely display much of if the file is non-ASCII) or -through 'strings'. The strings option is helpful for a quick analysis -of a binary file. - -

-Also shown is the file type. This is determined by running the 'file' -command on the output. It uses the magic header and footer values to -guess the file type. If the file type is an image or HTML, an option -will exist to View the data in its interpreted form (i.e. as -a picture or as a web page instead of the raw data). Note that -any HTML that is viewed will be processed in a sanitized environment -that does not load pictures and will not allow one to connect to a -remote site. To view the native picture, select 'Export' and open -the HTML document in another browser. Refer to issue #1 of The Sleuth -Kit Informer for more details on the sanitizing. - -

-The Report options create ASCII reports that contain the file -contents as well as data such as MD5 values and dates. - -

-The Export button extracts the file out of the image so you can save it -locally and use other tools on it. - -

-The Add Note button adds a personal note to the investigator log for -future reference. - -

-

References

-Issue 1 of The Sleuth -Kit Informer. - -
-Brian Carrier - diff --git a/help/fs_mode.html b/help/fs_mode.html deleted file mode 100644 index ef8ec4d760..0000000000 --- a/help/fs_mode.html +++ /dev/null @@ -1,46 +0,0 @@ - -Autopsy Image Details Help - - -

Image Details

- -

-

Overview

-Sometimes there are details about an image that do not correspond to -any file in particular. Those details can likely be found in this -mode. This mode gives the general details of the image and therefore -the contents will vary depending on the file system type. - -

-

FFS & EXT2FS

-For the UNIX file systems, this mode will contain the details from -the super block. This generally includes times that the file system -was last mounted and any special flags. It also has the range of -inode addresses and fragment addresses. For advanced file recovery, -you can also identify the group layout and on-disk structure details. -These could be useful for restricting where you search for data. -Files will allocate blocks and fragments in the same Cylinder or -Block group as their inode is in, so your attention can be restricted -to that area. - - -

-

FAT

-For FAT file systems, this mode will contain the File Allocation -Table. It will have the cluster runs, which can be selected to -view their contents in data unit -analysis mode. Or, if the file is fragmented, the pointer can -be selected and the screen will link to the next cluster chain. - - -

-

NTFS

-The unique information for an NTFS image is the numerical type -associated with attributes. These values can be dynamic and this -area will identify what they are for that file system. - - -

-


-Brian Carrier - diff --git a/help/general.html b/help/general.html deleted file mode 100644 index 5d20c6bbde..0000000000 --- a/help/general.html +++ /dev/null @@ -1,103 +0,0 @@ - -General Autopsy Help - - -

General Autopsy Help

-

-The Autopsy Forensic Browser is a graphical interface to command -line forensics tools and standard UNIX utilities. It allows -you to perform volume and file system analysis on UNIX and Windows systems. - -

-All data are saved in a directory in the Evidence Locker, which -was specified at install time or at run time. See -Case Management -for more information. In the normal mode, Autopsy imports an -image file from a disk or partition. In the live mode, Autopsy -can analyze a running system and does not save any data to the -local disk. - - -

-The browser has the following modes: -

    - -
  • -Files: -Allows you to browse the image file as a file system and view the -contents of files and directories. This mode even shows deleted -file names and Alternate Data Streams in NTFS images. You can sort -the files and directories on meta data. - -
  • -Meta Data: -Allows you to analyze the image file by examining the meta data structures. -The address of a structure is entered and the details are shown. -This mode is useful for examining unallocated structures and getting -all details about allocated files (including all data units and -other information such as MD5 value). - - -
  • -Data Unit: -Allows browsing by block number. This is most useful when used -with searching or meta data browsing. The contents of the block -can be displayed in ASCII, hex dump, or through strings(1). -The meta data structure that has allocated the block will be -displayed (if any) along with the file name (if any). - - -
  • -Keyword Search : -Search an image file using grep(1) for a given string or regular -expression. The result will be a list of data units that have the -string. Each data unit can be selected to view the contents. - - -
  • -Image Details: -List the details about the file or volume system. The output of -this mode depends on the file system. Examples of the file system -data include the last mount time, the last mount location, and a -detailed break down of block group information or File Allocation -Table contents. - -
  • -Image Integrity: -The integrity of the data can be validated at any -point by selecting this mode. It uses the values in md5.txt to -identify if any data have been modified in the analysis process. - -
  • -File Activity Timelines: -Autopsy can create timelines of file activity based on the Modified, -Access, and Change (Create in FAT/NTFS) times (MAC). The timeline -will contain details about deleted and allocated content. The -resulting timeline can be either viewed within Autopsy or using -other text viewing tools (WARNING: many HTML browsers do not handle -large tables like a timeline very well so using a text editor is -recommended). - -
  • -File Type Categories: -Autopsy can sort the files in an image file based on their file type. -For example, all JPEG and GIF files would be identified as images -and all executable files would be identified. This mode will also -ignore files that are found in hash databases of known good files, -identify files that are found in a hash database of known bad files, -and identify files that have an extension that is not consistent -with their file type. - - -
  • Report Generation: -Each of the above browsing techniques allows a report to be generated. -This report lists the date, md5 value, investigator, and other -context information in a text format. This can be used for record -keeping when deleted blocks of data have been found. - -
- - -
-Brian Carrier - diff --git a/help/grep.html b/help/grep.html deleted file mode 100644 index 1db6060075..0000000000 --- a/help/grep.html +++ /dev/null @@ -1,70 +0,0 @@ - -Autopsy grep Cheat Sheet - - -

grep Cheat Sheet

- -

Escaped Values

-Autopsy uses the grep utility to search an image. grep requires -that some values be "escaped" if they are searched for. Autopsy -will automatically escape those values if the serach is being done for -a non-regular expression. The escaped values include: -
    -
  • \ -
  • . -
  • [ -
  • ^ -
  • $ -
  • ' -
  • * -
  • initial - -
- - -

Regular Expressions

-Refer to the man page for 'grep' for more details of creating regular -expressions. Autopsy uses the '-E' flag with 'grep' to specify -extended regular expressions. The following have special meaning -with grep: - -
    -
  • [A-Za-z]: Any lower and upper case letter -
  • [:alpha:]: same as above -
  • [0-9]: Any number -
  • [:digit:]: same as above -
  • [0-9A-Za-z]: Any lower and upper case letter or digit -
  • [:alnum:]: same as above -
  • [:space:]: Any white space -
- - -

-To specify how many times something can occur, the following are used: -

    -
  • ?: Optional and can only occur once -
  • *: Optional and can occur more than once -
  • +: Required and can occur more than once -
- -

-To specify more than one string to match, use the | operator. - -

Examples

- -

-To search for 'Jane Smith' or 'Jack Smith': (Jane)|(Jack) Smith - -

-To ensure it matches if a tab is between the first and last name: -(Jane)|(Jack)[:space:]Smith - -

-To search for 'Jane Smith' or 'Jane Anne Smith': -Jane( Anne)? Smith - -

-or: Jane([:space:]Anne)?[:space:]Smith - -


-Brian Carrier - diff --git a/help/grep_lim.html b/help/grep_lim.html deleted file mode 100644 index d8a29d27e5..0000000000 --- a/help/grep_lim.html +++ /dev/null @@ -1,75 +0,0 @@ - -Autopsy grep Search Limitations - - -

grep Search Limitations

- -

Overview

-

-Keyword searches are very basic in Autopsy. Autopsy uses the -strings and grep tools on the image and when a -hit is found, it uses ifind and ffind to identify -the file that has allocated the string. This is a very simple and -basic method of searching and is not ideal. This will cause false -positives and will miss data that crosses a fragmented part of a file. -The limitations are outlined in this file. - -

What Will Be Found

-strings is first run on the image and the data is passed -to grep to do the actual search. This process will find -ASCII and UNICODE strings that are consecutive anywhere in the file. This is -frequently referred to as the physical layout. For example, it -will find strings in the middle of an allocated sector, in an -unallocated sector, in slack space, and in meta data strutures. -This will find a string that crosses sectors, which is good if the -two sectors are for the same file. - -

-This technique leads to several types of false positives. For example, -a string that crosses from the allocated space of a file into the slack -space would be found by grep. A string that starts in the slack space -and ends in the allocated space of a file will also be found. A string -that crosses sectors of two different allocated files will also be found. The -user must identify if the hit is an actual hit or a false positive. - -

What Will Be Found, but May Be Confusing

-

-If you are searching with regular expressions, then the exact -location and number of hits may not be correctly reported. If the -count is incorrect, then it will be too small. If the location -is incorrect, then it will be too early (and could even be in the -next data unit). The reason that this is in accurate is because -the grep tool will return a long string to Autopsy that -will contain one or more occurances of the keyword. Autopsy can -not search the long string to find the exact number and location -of the regular expression keywords like it can for non-regular -expression keywords, so it returns only the starting location of -the long string. - -

What Will NOT Be Found

-The biggest category of 'hits' that will not occur using this technique -is strings in a file that cross fragmented data units. For example, consider -a file that has two clusters allocated, cluster 100 and cluster 150. A -string "mississippi" could have "missi" in the final 5 bytes of cluster 100 -and "ssippi" in the initial 6 bytes of cluster 150. The string exists from -the logial level, but not at the physical level. Therefore, the grep -search would not find the string. - -

-Although not because of grep, Autopsy will also not find -data in the slack space during an unallocated-only search. The -extraction tool for The Sleuth Kit (blkls) differentiates -between unallocated sectors in FAT and NTFS and slack space. There -is currently no way in Autopsy to extract the slack space and search -it. Autopsy currently only extracts the unallocated sectors and not -the allocated sectors that may have deleted data in them. - - -

Conclusion

-Autopsy has basic keyword search functionality. Future versions may provide -more features and better search results. In the mean time, it is important -that users understand the abilities and limitations of the tool so that they -can be taken into account during the investigation. -
-Brian Carrier - diff --git a/help/hash_db.html b/help/hash_db.html deleted file mode 100644 index cddb793866..0000000000 --- a/help/hash_db.html +++ /dev/null @@ -1,141 +0,0 @@ - -Autopsy Hash Database Help - - -

Hash Database Help

- -

Overview

-Hash databases are used to quickly identify known good and known -bad files using the MD5 or SHA-1 checksum value. Autopsy uses -three types of hash databases to help the investigator reduce the -number of files that they have to look at. - -

-The NIST National Software Reference Library (NSRL) contains -hashes of files that are found in operating systems and software -distributions. These files are known to be good in that they came -from trusted sources and are typically on authorized systems. When -processing files in the image, this database can be used to ignore -files because they are assumed to be known and therefore uninteresting. -The location of this database is configured when Autopsy is installed. -The NSRL must be obtained from NIST at www.nsrl.nist.gov. - -

-The Ignore Database is a database that the investigator must -create. It is similar to the NIST NSRL in that it contains files -that are known to be good and can be ignored if the user -chooses to do so (only applicable when in File -Type Category Analysis). Examples of files in this category include -system binaries for standard builds. See Database -Creation for information on creating this database. Its location -is configured when the host is created and can be edited in the -host configuration file. - -

-The Alert Database is a database that the investigator must -create. It contains hashes of known bad files. These are -the files that an investigator wants to know about if they exist -on the system. Examples of this include rootkits or unauthorized -photographs. -When using the File Type Category -Analysis, these files will be saved in a special file. See Database Creation for information on creating -this database. Its location is configured when the host is created -and can be edited in the host configuration file. - - -

Database Uses

-Autopsy uses the hash databases in three ways. - -
    -
  • File Type Category Analysis: The - hash databases are used to identify the known bad files and - ignore the known good files. - -
  • Meta Data Analysis: The hash - databases can be used to identify a file from the meta data view. If - the databases are configured, the hash from a given file can be looked - up by pressing the 'lookup' button. - All three databases can be used in this view. This view can be found - from the File Analysis mode by selecting the meta data address in - the directory listing window. - -
  • Hash Database Manager: From the Host Gallery view, - the Hash Database Manager can be entered. This is where one can - re-index the databases and perform single lookups in any of the - databases. -
- - - -

Database Creation

-Currently, Autopsy will only allows one to look entries up in a -hash database. It does not allow one to easily create a database, -but this will describe the process (it is quite simple). - -

-Autopsy uses the hfind tool from The Sleuth Kit to do the -lookups. This tool requires the database to be indexed so that it -can perform a fast lookup using a binary search algorithm (instead -of a slower sequential search that a tool like grep would do). -When ever a hash database is updated (or created), it must be -indexed. This can be done in Autopsy in the Hash Database Manager -(Note that the database must already be configured though). - -

-The NIST NSRL obviously does not have to be created, but it does have -to be indexed before it is used. - -

-To make a hash database, we will create a file with the same format -as the md5sum command uses. This is just the MD5 hash, -some white space, and the file name. For example:
- -    c4a6761b486de3c6abf7cf2c554289e5 -    /bin/ps

- -Make a file with this format for every line (it does not have to -be sorted). For example, if you have a trusted system then you can make -a hash database of its system binaries using the following:
- -    # md5sum /bin/* /sbin/* > bin-md5.db

- -After creation, hash databases must be indexed and sorted (this -includes the NSRL). Databases will be indexed by using the -hfind tool. The NSRL database would be indexed with:
- -    # hfind -i nsrl-md5 PATH_TO_NSRL/NSRLFile.txt

- -A database made by md5sum would be indexed with:
- -    # hfind -i md5sum bin-md5.db

- -Or, if Autopsy has this file configured from when the host was added, -then it can be re-indexed from the Hash Database Manager. - -

Autopsy Configuration

-The alert and ignore databases are stored in the host configuration file -with the headers of 'exclude_db' and 'alert_db'. For example:
- -    alert_db    '/usr/local/hash/bad.db'

-These entries can be edited at any time. - -

-The NSRL database is configured in the conf.pl file in the -directory where Autopsy was installed. It has the $NSRLDB variable. -For example:
- -    $NSRLDB = '/usr/local/hash/nsrl/NSRLFile.txt';

- -It can be edited, added, and removed at any time (but you must restart -Autopsy). - - -

-

References

-Issues 6 and 7 of
The -Sleuth Kit Informer discussed hash databases. - -
-Brian Carrier - diff --git a/help/index.html b/help/index.html deleted file mode 100644 index c7c46aec4f..0000000000 --- a/help/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Autopsy Help - - - - - - - - - diff --git a/help/int_mode.html b/help/int_mode.html deleted file mode 100644 index 5152b95ad0..0000000000 --- a/help/int_mode.html +++ /dev/null @@ -1,29 +0,0 @@ - -Autopsy Integrity Check Help - - -

Integrity Check

- -

Overview

-It is always important to validate the integrity of images during -an analysis. Autopsy uses the MD5 algorithm to validate images -and other files that are created by Autopsy. - -

-The md5.txt files contain the MD5 values for files in that -directory. Values are added to it when file system images are -imported into the system or when Autopsy creates the file. This mode -allows one to calculate the MD5 value if it was not created before -and to validate the integrity. - -

-When the Image Integrity button is selected from the Host -Manager window, all files will be shown with their MD5 value -if known. Here any image can have its value verified or a new one -created. - - -

-


-Brian Carrier - diff --git a/help/menu.html b/help/menu.html deleted file mode 100644 index 8b74a86594..0000000000 --- a/help/menu.html +++ /dev/null @@ -1,37 +0,0 @@ - -Autopsy Help Topics - - -

General Information - -

Case Management - -


- -

File Analysis - -

Meta Data Analysis - -

Data Unit Analysis - -

Image Details - -

Keyword Searching - -

grep Cheat Sheet - -

grep Search Limitations - -

Timelines - -

Event Sequencer - -

File Type Categories - -

Hash Databases - -

Image Integrity - -

Time Zones - - diff --git a/help/meta_mode.html b/help/meta_mode.html deleted file mode 100644 index 3a7475f713..0000000000 --- a/help/meta_mode.html +++ /dev/null @@ -1,93 +0,0 @@ - -Autopsy Metadata Analysis Help - - -

Metadata Analysis

-

Overview

-The Metadata Analysis mode allows the investigator to view the -details of metadata structures. The metadata structures on the -on-disk structures that contain the details of a file, such as -times and pointers to the allocated data units. FFS and EXT2FS -file systems call them inode structures, NTFS file systems call -them Master File Table (MFT) entries (or File Entries), and the -FAT file system calls them directory entries. This mode is useful -for recovering data and getting a detailed look at a file. - -

Input

-To view the contents of a structure, enter the address in the text -box on the left and select Display. - -

-The Allocation List button can also be used to view the -allocation status of metadata structures in groups of 500. - -

Viewing

-The structure details are displayed on the right-hand side. -Typically, the metadata structure does not have the name of the -file that uses that structure, so Autopsy will try to locate the -file name. This process is slow with a FAT file system, so it is -not done by default. - -

-The File Type is given, which is the output of the 'file' -tool. This tool uses any header information in the file to -guess what its type is. The MD5 value of the file is also given. - -

-If Autopsy has been configured to use hash databases, then one can -select which databases to look for the file in. See -Hash Databases for more details. - -

-The rest of the information will vary depending on the file -system type. In general, the allocation status will be given as -well as the size and each data unit that it has allocated. A -link will exist for each data unit that will show its contents. - -

-The Report option generates an ASCII report with the structure -details, MD5 values, and dates in it. The View Contents option -displays the allocated data contents as one large file. The Export -option allows one to save the data contents to a file. The -Add Note button allows one to add a comment about this structure so -that it can be later recalled. - -

NTFS Notes

-

-NTFS is a much different design than UNIX file systems and the meta -data structures are addressed differently. They typically have -the form of A-B-C, 88-128-3 for example. The -A value is the address of the file in the Master File -Table, 88 for example. This is similar to the inode value in UNIX. -Each file has several attributes, including at least one in files -for the data. The B value is the type of attribute. In -most cases, the data attribute has a type of 128 so this is commonly -seen. But, if you want to see the file name attribute, you could -specify that type and see the contents if you like (it is fairly -boring). The final value, C, is the id. Every attribute -has a unique id value. So, if there are multiple attributes with -the same type, you can specify the type. - -

FAT Notes

-

-FAT does not give addresses to the directory entry structures. in -FAT, directory entries can be stored anywhere on the disk. They -are stored in the clusters allocated to the parent directory. This -is unlike NTFS or UNIX where the structures are in a large table -that does not move. get around that, - - -

-The addressing issue was solved by providing an address to every -32-byte area in the Data Area. Whether that data was currently a -directory entry or not. This makes it easy to find a given address -and scale when new files are created. The downside is that not -every address is possible, so it is likely that you will see jumps -in the address values. See the documentation in The Sleuth Kit -for more details. - - -

-


-Brian Carrier - diff --git a/help/sequencer.html b/help/sequencer.html deleted file mode 100644 index 6afb01e3e7..0000000000 --- a/help/sequencer.html +++ /dev/null @@ -1,49 +0,0 @@ - -Autopsy Event Sequencer Help - - -

Event Sequencer

- -

Overview

-

-In many investigations, evidence is not found in the order that it was -created during the incident. The notes feature in Autopsy allows one to -make notes about certain files, but it does not help one to put a -series of events in order. - -

-The Event Sequencer allows the investigator to make notes and comments -about pieces of evidence. Each note must have a time associated with -it. For files and meta data, the times can be one or more of the -MAC times. Other notes can have times entered manually. The sequencer -will sort the events after each is entered so that the investigator can -quickly identify where there are gaps in the findings. - -

Adding an Event

-

-To add an event for a file, directory, or meta data structure, select -the Add Note button. At the bottom will be check boxes that allow -an event to be generated for each of the file's times. The "standard" -note does not have to be generated if it is not needed. - -

-To add an event from a different source, go to the Event Sequencer from -the Host Gallery (where the images are listed). At the bottom of -the window will be an area where the new event can be added. The -Source of the event will be shown where the file name of -a file event is normally shown. Examples of this type include -entries from firewall logs or reports from the help desk. - -

Viewing the Sequence Events

-

-The Event Sequencer button can be found in the Host Gallery. -This window shows the events that are sorted by the time. Events that -correspond to a file, directory, or meta data structure will have either -[M-Time], [A-Time], or [C-Time] in the note that shows what time this -event was generated from. Clicking on the name will show the contents of -the file or directory. - - -


-Brian Carrier - diff --git a/help/srch_mode.html b/help/srch_mode.html deleted file mode 100644 index 43b65791be..0000000000 --- a/help/srch_mode.html +++ /dev/null @@ -1,68 +0,0 @@ - -Autopsy Keyword Search Help - - - -

Keyword Search

-

Overview

-

-This mode searches an image for a given string. This is most useful -when searching for deleted content. To decrease the time required -for a search, a "strings" file can serve as an index. This file -will contain only the ASCII strings in the image. - -

-Autopsy will also prompt you to create a file of unallocated data if one -does not exist. This obviously is useful for recovering deleted data. -If a string is found in this file, Autopsy will also report the location -in the original image. - -

Entering the String

- -Enter the string or regular expression into the text box. Autopsy -allows you to search for a either a specific string or using 'grep' -style regular expressions. A case insensitive search will occur -if the appropriate box is checked, otherwise it is case sensitive. -You will also have the option of searching for the string as an -ASCII or a Unicode string. Unicode is much more common in Windows -systems than Unix systems. If both types are selected, then two -searches will be done. - -

-If you have not generated a strings file or unallocated data file yet, -that option will exist. - -

-The Load Unallocated Image or Load Allocated Image button -exists to switch between the two file types if they have both been -generated. - -

-Autopsy also has the ability to perform pre-configured searches. They -are shown in the "Predefined Searches" section. - -

Viewing the Results

-After the image has been searched, a list of "hits" will appear on the -left-hand side. Each data unit that contains the string is listed with -the offset of each occurrence. If a regular expression is used, then the -exact location is not given. - -

-If the search was done on an unallocated data file, then an option will -exist next to each address to also view the original. Doing so could -reveal the inode that allocated it. - -

Previous Searches

-The search results are saved to a file so it is easy to recall the -results with out having to perform the search again. - -

Regular Expressions

-You can use grep regular expressions in the search -(refer to the 'grep' -help page and man page for more details). To search for -a couple of different words you would use: (foo) | (bar). - - -
-Brian Carrier - diff --git a/help/temp.html b/help/temp.html deleted file mode 100644 index c3a4b95ee9..0000000000 --- a/help/temp.html +++ /dev/null @@ -1,10 +0,0 @@ - -Autopsy File Analysis Help - - - - - -
-Brian Carrier - diff --git a/help/timezones.html b/help/timezones.html deleted file mode 100644 index 6fa95b7c21..0000000000 --- a/help/timezones.html +++ /dev/null @@ -1,508 +0,0 @@ - -Autopsy File Analysis Help - Time zone - - -

- -When creating a host, you can specify a time zone. If you do not, it will default to the time zone to which your system is set. If the system being investigated came from a different time zone, then you need to figure out what it was called. Below are a list of time zones that are known by most computers. - -


-This list was copied from this site: -http://showtunepink.com/ical/TIMEZONES - -

-
-Africa/Addis_Ababa
-Africa/Algiers
-Africa/Asmera
-Africa/Bangui
-Africa/Blantyre
-Africa/Brazzaville
-Africa/Bujumbura
-Africa/Cairo
-Africa/Ceuta
-Africa/Dar_es_Salaam
-Africa/Djibouti
-Africa/Douala
-Africa/Gaborone
-Africa/Harare
-Africa/Johannesburg
-Africa/Kampala
-Africa/Khartoum
-Africa/Kigali
-Africa/Kinshasa
-Africa/Lagos
-Africa/Libreville
-Africa/Luanda
-Africa/Lubumbashi
-Africa/Lusaka
-Africa/Malabo
-Africa/Maputo
-Africa/Maseru
-Africa/Mbabane
-Africa/Mogadishu
-Africa/Nairobi
-Africa/Ndjamena
-Africa/Niamey
-Africa/Porto-Novo
-Africa/Tripoli
-Africa/Tunis
-Africa/Windhoek
-America/Adak
-America/Anchorage
-America/Anguilla
-America/Antigua
-America/Araguaina
-America/Aruba
-America/Asuncion
-America/Atka
-America/Barbados
-America/Belem
-America/Belize
-America/Boa_Vista
-America/Bogota
-America/Boise
-America/Buenos_Aires
-America/Cambridge_Bay
-America/Cancun
-America/Caracas
-America/Catamarca
-America/Cayenne
-America/Cayman
-America/Chicago
-America/Chihuahua
-America/Cordoba
-America/Costa_Rica
-America/Cuiaba
-America/Curacao
-America/Dawson
-America/Dawson_Creek
-America/Denver
-America/Detroit
-America/Dominica
-America/Edmonton
-America/Eirunepe
-America/El_Salvador
-America/Ensenada
-America/Fort_Wayne
-America/Fortaleza
-America/Glace_Bay
-America/Godthab
-America/Goose_Bay
-America/Grand_Turk
-America/Grenada
-America/Guadeloupe
-America/Guatemala
-America/Guayaquil
-America/Guyana
-America/Halifax
-America/Havana
-America/Hermosillo
-America/Indiana/Indianapolis
-America/Indiana/Knox
-America/Indiana/Marengo
-America/Indiana/Vevay
-America/Indianapolis
-America/Inuvik
-America/Iqaluit
-America/Jamaica
-America/Jujuy
-America/Juneau
-America/Kentucky/Louisville
-America/Kentucky/Monticello
-America/Knox_IN
-America/La_Paz
-America/Lima
-America/Los_Angeles
-America/Louisville
-America/Maceio
-America/Managua
-America/Manaus
-America/Martinique
-America/Mazatlan
-America/Mendoza
-America/Menominee
-America/Merida
-America/Mexico_City
-America/Miquelon
-America/Monterrey
-America/Montevideo
-America/Montreal
-America/Montserrat
-America/Nassau
-America/New_York
-America/Nipigon
-America/Nome
-America/Noronha
-America/Panama
-America/Pangnirtung
-America/Paramaribo
-America/Phoenix
-America/Port-au-Prince
-America/Port_of_Spain
-America/Porto_Acre
-America/Porto_Velho
-America/Puerto_Rico
-America/Rainy_River
-America/Rankin_Inlet
-America/Recife
-America/Regina
-America/Rio_Branco
-America/Rosario
-America/Santiago
-America/Santo_Domingo
-America/Sao_Paulo
-America/Scoresbysund
-America/Shiprock
-America/St_Johns
-America/St_Kitts
-America/St_Lucia
-America/St_Thomas
-America/St_Vincent
-America/Swift_Current
-America/Tegucigalpa
-America/Thule
-America/Thunder_Bay
-America/Tijuana
-America/Tortola
-America/Vancouver
-America/Virgin
-America/Whitehorse
-America/Winnipeg
-America/Yakutat
-America/Yellowknife
-Antarctica/Casey
-Antarctica/Davis
-Antarctica/DumontDUrville
-Antarctica/Mawson
-Antarctica/McMurdo
-Antarctica/Palmer
-Antarctica/South_Pole
-Antarctica/Syowa
-Antarctica/Vostok
-Arctic/Longyearbyen
-Asia/Aden
-Asia/Almaty
-Asia/Amman
-Asia/Anadyr
-Asia/Aqtau
-Asia/Aqtobe
-Asia/Ashgabat
-Asia/Ashkhabad
-Asia/Baghdad
-Asia/Bahrain
-Asia/Baku
-Asia/Bangkok
-Asia/Beirut
-Asia/Bishkek
-Asia/Brunei
-Asia/Calcutta
-Asia/Chungking
-Asia/Colombo
-Asia/Dacca
-Asia/Damascus
-Asia/Dhaka
-Asia/Dili
-Asia/Dubai
-Asia/Dushanbe
-Asia/Gaza
-Asia/Harbin
-Asia/Hong_Kong
-Asia/Hovd
-Asia/Irkutsk
-Asia/Istanbul
-Asia/Jakarta
-Asia/Jayapura
-Asia/Jerusalem
-Asia/Kabul
-Asia/Kamchatka
-Asia/Karachi
-Asia/Kashgar
-Asia/Katmandu
-Asia/Krasnoyarsk
-Asia/Kuala_Lumpur
-Asia/Kuching
-Asia/Kuwait
-Asia/Macao
-Asia/Magadan
-Asia/Manila
-Asia/Muscat
-Asia/Nicosia
-Asia/Novosibirsk
-Asia/Omsk
-Asia/Phnom_Penh
-Asia/Pyongyang
-Asia/Qatar
-Asia/Rangoon
-Asia/Riyadh
-Asia/Riyadh87
-Asia/Riyadh88
-Asia/Riyadh89
-Asia/Saigon
-Asia/Samarkand
-Asia/Seoul
-Asia/Shanghai
-Asia/Singapore
-Asia/Taipei
-Asia/Tashkent
-Asia/Tbilisi
-Asia/Tehran
-Asia/Tel_Aviv
-Asia/Thimbu
-Asia/Thimphu
-Asia/Tokyo
-Asia/Ujung_Pandang
-Asia/Ulaanbaatar
-Asia/Ulan_Bator
-Asia/Urumqi
-Asia/Vientiane
-Asia/Vladivostok
-Asia/Yakutsk
-Asia/Yekaterinburg
-Asia/Yerevan
-Atlantic/Azores
-Atlantic/Bermuda
-Atlantic/Canary
-Atlantic/Cape_Verde
-Atlantic/Faeroe
-Atlantic/Jan_Mayen
-Atlantic/Madeira
-Atlantic/South_Georgia
-Atlantic/Stanley
-Australia/ACT
-Australia/Adelaide
-Australia/Brisbane
-Australia/Broken_Hill
-Australia/Canberra
-Australia/Darwin
-Australia/Hobart
-Australia/LHI
-Australia/Lindeman
-Australia/Lord_Howe
-Australia/Melbourne
-Australia/NSW
-Australia/North
-Australia/Perth
-Australia/Queensland
-Australia/South
-Australia/Sydney
-Australia/Tasmania
-Australia/Victoria
-Australia/West
-Australia/Yancowinna
-Brazil/Acre
-Brazil/DeNoronha
-Brazil/East
-Brazil/West
-CET
-CST6CDT
-Canada/Atlantic
-Canada/Central
-Canada/East-Saskatchewan
-Canada/Eastern
-Canada/Mountain
-Canada/Newfoundland
-Canada/Pacific
-Canada/Saskatchewan
-Canada/Yukon
-Chile/Continental
-Chile/EasterIsland
-Cuba
-EET
-EST
-EST5EDT
-Egypt
-Eire
-Etc/GMT+1
-Etc/GMT+10
-Etc/GMT+11
-Etc/GMT+12
-Etc/GMT+2
-Etc/GMT+3
-Etc/GMT+4
-Etc/GMT+5
-Etc/GMT+6
-Etc/GMT+7
-Etc/GMT+8
-Etc/GMT+9
-Etc/GMT-1
-Etc/GMT-10
-Etc/GMT-11
-Etc/GMT-12
-Etc/GMT-13
-Etc/GMT-14
-Etc/GMT-2
-Etc/GMT-3
-Etc/GMT-4
-Etc/GMT-5
-Etc/GMT-6
-Etc/GMT-7
-Etc/GMT-8
-Etc/GMT-9
-Europe/Amsterdam
-Europe/Andorra
-Europe/Athens
-Europe/Belfast
-Europe/Belgrade
-Europe/Berlin
-Europe/Bratislava
-Europe/Brussels
-Europe/Bucharest
-Europe/Budapest
-Europe/Chisinau
-Europe/Copenhagen
-Europe/Dublin
-Europe/Gibraltar
-Europe/Helsinki
-Europe/Istanbul
-Europe/Kaliningrad
-Europe/Kiev
-Europe/Lisbon
-Europe/Ljubljana
-Europe/London
-Europe/Luxembourg
-Europe/Madrid
-Europe/Malta
-Europe/Minsk
-Europe/Monaco
-Europe/Moscow
-Europe/Nicosia
-Europe/Oslo
-Europe/Paris
-Europe/Prague
-Europe/Riga
-Europe/Rome
-Europe/Samara
-Europe/San_Marino
-Europe/Sarajevo
-Europe/Simferopol
-Europe/Skopje
-Europe/Sofia
-Europe/Stockholm
-Europe/Tallinn
-Europe/Tirane
-Europe/Tiraspol
-Europe/Uzhgorod
-Europe/Vaduz
-Europe/Vatican
-Europe/Vienna
-Europe/Vilnius
-Europe/Warsaw
-Europe/Zagreb
-Europe/Zaporozhye
-Europe/Zurich
-GB
-GB-Eire
-GMT
-HST
-Hongkong
-Indian/Antananarivo
-Indian/Chagos
-Indian/Christmas
-Indian/Cocos
-Indian/Comoro
-Indian/Kerguelen
-Indian/Mahe
-Indian/Maldives
-Indian/Mauritius
-Indian/Mayotte
-Indian/Reunion
-Iran
-Israel
-Jamaica
-Japan
-Kwajalein
-Libya
-MET
-MST
-MST7MDT
-Mexico/BajaNorte
-Mexico/BajaSur
-Mexico/General
-Mideast/Riyadh87
-Mideast/Riyadh88
-Mideast/Riyadh89
-NZ
-NZ-CHAT
-Navajo
-PRC
-PST8PDT
-Pacific/Apia
-Pacific/Auckland
-Pacific/Chatham
-Pacific/Easter
-Pacific/Efate
-Pacific/Enderbury
-Pacific/Fakaofo
-Pacific/Fiji
-Pacific/Funafuti
-Pacific/Galapagos
-Pacific/Gambier
-Pacific/Guadalcanal
-Pacific/Guam
-Pacific/Honolulu
-Pacific/Johnston
-Pacific/Kiritimati
-Pacific/Kosrae
-Pacific/Kwajalein
-Pacific/Majuro
-Pacific/Marquesas
-Pacific/Midway
-Pacific/Nauru
-Pacific/Niue
-Pacific/Norfolk
-Pacific/Noumea
-Pacific/Pago_Pago
-Pacific/Palau
-Pacific/Pitcairn
-Pacific/Ponape
-Pacific/Port_Moresby
-Pacific/Rarotonga
-Pacific/Saipan
-Pacific/Samoa
-Pacific/Tahiti
-Pacific/Tarawa
-Pacific/Tongatapu
-Pacific/Truk
-Pacific/Wake
-Pacific/Wallis
-Pacific/Yap
-Poland
-Portugal
-ROC
-ROK
-Singapore
-SystemV/AST4
-SystemV/AST4ADT
-SystemV/CST6
-SystemV/CST6CDT
-SystemV/EST5
-SystemV/EST5EDT
-SystemV/HST10
-SystemV/MST7
-SystemV/MST7MDT
-SystemV/PST8
-SystemV/PST8PDT
-SystemV/YST9
-SystemV/YST9YDT
-Turkey
-US/Alaska
-US/Aleutian
-US/Arizona
-US/Central
-US/East-Indiana
-US/Eastern
-US/Hawaii
-US/Indiana-Starke
-US/Michigan
-US/Mountain
-US/Pacific
-US/Samoa
-W-SU
-WET
-
-
- -
-Brian Carrier - diff --git a/help/tl.html b/help/tl.html deleted file mode 100644 index 621165414b..0000000000 --- a/help/tl.html +++ /dev/null @@ -1,183 +0,0 @@ - -Autopsy Timeline Analysis Help - - -

Timeline Mode

-

Overview

-

-For some investigations, creating a timeline of activity can be -useful to identify places where the analysis should begin. Of -course file times can be easily modified by an attacker, so they -can not be 100% trusted. But, Autopsy can create timelines of -file activity. - -

-Files have at least three times associated with them. The details of -each time varies with the file system type. - -

-The following times exist for UNIX file systems (EXT2FS & FFS): - -

    -
  • Modified: When the file data was last - modified. This time can be modified using the utimes() - function. This time is preserved in a 'tar' archive, so it is - possible to have M-times of files prior to when they were introduced - to the system. - -
  • Accessed: When the file data was last - accessed. This time can be modified using the utimes() function. - -
  • Changed: When the file status (inode data) - was last changed. This time can not be set using the utimes() - function in UNIX (but it will be set when utimes() is used to modify - other values). -
- -The EXT2FS file system also has a Deleted time, but it is not displayed -in the timeline. - -

-A FAT File system has the following times: -

    -
  • Written: When the file was last written to. - It is the ONLY required time in the FAT file system. - -
  • Accessed: When the file was last accessed. In - FAT, it is only accurate to the day (not minute). It is an optional - value, so some Operating Systems may not update it. - -
  • Created: When the file was created. It is - also optional, so some Operating Systems may not update it. In fact, - many Windows installations have a C-Time of 0 for directories such as - C:\\Windows and C:\\Program Files. -
- -

-The NTFS File system has several times, four of which are -used in the timeline. These times are gathered from the -\$STANDARD_INFORMATION attribute. -

    -
  • Written: When the file was last written to. - -
  • Accessed: When the file was last accessed. - -
  • Changed: When the MFT entry was last modified. - -
  • Created: When the file was created. -
- - -

How to Create a Timeline

-Creating a timeline takes two steps. The first step extracts and -saves the needed data from each file system images. This step -stores the data from each specific file system in a generic format. -Historically (from TCT), this file was called the body -file. The second step takes the body file as input and -generates an ASCII timeline of file activity between two specified -dates. The resulting timeline can be viewed in Autopsy or using -a text editor. - - -

Creating the Body File

-The file meta-data must be extracted from the file system images and saved -to the body file. There are three major types of files that data -can be extracted for: -
    -
  • Allocated Files: -Files that are seen when doing an 'ls' or 'dir' in a directory. In -other words, these are the files that have an allocated file name -structure. - -
  • Unallocated Files: -Files that have been deleted, but that TSK can still access. -Files in this category include orphan files, which are files that -no longer have a name, but whose metadata still exists. -If a deleted file name points to an allocated metadata structure, -then the name will say (realloc) next to it. - -
- -

-To create the body file, select the images to analyze from -the list on top. Next, select which types of data that you want to -extract. By default all types are extracted. Lastly, identify the -name of the body file to create. The file will be created in the -output directory and an entry will be added to the host config -file. You will be given the option to calculate the MD5 value of -the new file. - - -

Creating the Timeline

-The next window allows one to create a timeline based on the newly -created body file. Or, one can select the option from -the left-hand side menu. The range of dates must be selected as -well as the name of the timeline file. The resulting timeline will -use the time zone for the host. - -

-If the images are from a -UNIX file system, then the password and group files can be used to -change the UID and GID to actual names. If the partition from the -root directory exists in the host, select it from the pull down -list and Autopsy will find the /etc/passwd and -/etc/group file contents. - -

-The timeline will be created in the output directory. -You will be given the option to calculate the MD5 hash value of -the new file. - -

Viewing the Timeline

-The timeline can be viewed in Autopsy. Timelines tend to be very -large though and have thousands of lines. HTML browsers can not -handle tables of this size very well and typically have trouble -processing it. Therefore, Autopsy only allows you to view the -timeline one month at a time. It will likely be easier to open a -shell and examine the timeline in a text editor or pager such as -'less' or 'more'. - -

-The 'summary' link will show a page that contains a monthly summary -of activity. It shows how many many events occured in that month -and links to the details. This allows one to get a high level -view of when a lot of activity last occured. - -

-The following columns are in the timeline (in order): -

    -
  • Date and timeof the activity. If no date is given, - then the activity occured at the same time as the previous entry - with a time. - -
  • Size. The size of the file. - -
  • Entry Type. The 'm', 'a', 'c', and 'b' letters will exist to - identify which of the activity types this entry corresponds to. 'm' is - for modified times, 'a' is for access times, 'c' is for change times, and - 'b' is for created (or born) times. - -
  • ModeUID. The User Id or User name is shown. If a password - file was provided when the timeline was created, then the colunn should - only have names. - -
  • GID. The Group Id or Group name is shown. If a group - file was provided when the timeline was created, then the colunn should - only have names. - -
  • Meta Data Address. The inode or MFT entry address for the - associated file. - -
  • File Name. The name of the file and the destination of a - symbolic link. Deleted entries will have '(deleted)' at the end and - deleted entries that point to an allocated meta data structure will - have '(realloc)'. - - -
- -
-Brian Carrier - diff --git a/lib/.perltidyrc b/lib/.perltidyrc deleted file mode 100755 index f1f2e71a01..0000000000 --- a/lib/.perltidyrc +++ /dev/null @@ -1,5 +0,0 @@ --i=4 # indent of 4 --pt=2 # paren tightness --sbt=2 # square paren tightness --bt=2 # curly paren tightness --nsfs # no space after semi in for loop diff --git a/lib/Appsort.pm b/lib/Appsort.pm deleted file mode 100644 index bdf82bfad6..0000000000 --- a/lib/Appsort.pm +++ /dev/null @@ -1,399 +0,0 @@ -# -# Sort files based on their application type (content) -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2008 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 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. - -package Appsort; - -$Appsort::FRAME = 1; -$Appsort::MENU = 2; -$Appsort::ENTER = 3; -$Appsort::RUN = 4; -$Appsort::VIEW = 5; -$Appsort::BLANK = 6; - -sub main { - - if ($::LIVE == 1) { - Print::print_html_header("Unsupported for Live Analysis"); - print -"

This feature is not available during a live analysis

"; - Print::print_html_footer(); - return 0; - } - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $Appsort::FRAME - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - if ($view == $Appsort::BLANK) { - return blank(); - } - - # Check Basic Args - Args::check_vol('vol'); - - # These windows don't need the meta data address - if ($view == $Appsort::FRAME) { - return frame(); - } - elsif ($view == $Appsort::ENTER) { - return enter(); - } - elsif ($view == $Appsort::MENU) { - return menu(); - } - elsif ($view == $Appsort::RUN) { - return run(); - } - elsif ($view == $Appsort::VIEW) { - return view(); - } - else { - Print::print_check_err("Invalid Application Sorting View"); - } -} - -sub get_sorter_dir { - if ($Args::args{'vol'} =~ /^($::REG_VNAME)$/) { - return "$::host_dir" . "$::DATADIR/sorter-$1/"; - } - Print::print_err("Invalid Sorter Directory"); -} - -sub get_sorter_graphics_dir { - if ($Args::args{'vol'} =~ /^($::REG_VNAME)$/) { - return "$::host_dir" . "$::DATADIR/sorter-graphics-$1/"; - } - Print::print_err("Invalid Sorter Graphics Directory"); -} - -# sorter frameset -sub frame { - Print::print_html_header_frameset("Sorter on $Args::args{'vol'}"); - - print "\n"; - - # Block List - print "\n"; - - # Blank - print "\n" - . "\n"; - - Print::print_html_footer_frameset(); - return 0; -} - -# The left-hand frame for running sorter -sub menu { - Print::print_html_header("sorter menu"); - - print "

Sort Files by Type"; - - print "

View Sorted Files"; - - Print::print_html_footer(); - return 0; -} - -# Get the data and print the form so that sorter can be run -sub enter { - Print::print_html_header("sorter - enter data to create"); - - print "

" - . "

File Type Sortings


" - . "
\n" - . "\n" - . "\n" - . "\n" - . Args::make_hidden(); - - print <The sorter tool will process an image and organize the -files based on their file type. The files are organized into categories -that are defined in configuration files. The categories will be saved -in the $::DATADIR directory. -
-EOF1 - - my $sort_dir = get_sorter_dir(); - if (-d "$sort_dir") { - print "WARNING: This will overwrite any existing data in:
" - . "    $sort_dir
\n"; - } - - my $tab = "        "; - - print < - -Sort files into categories by type - -

$tab - - Do not save data about unknown file types - -

$tab - - Save a copy of files in category directory (may require lots of disk space) - -

$tab - - Save ONLY graphic images and make thumbnails
- $tab (may require lots of disk space and will save to a different directory than sorting all file types) - -

- -Extension and File Type Validation - -EOF2 - - if (($::NSRLDB ne "") && (-e "$::NSRLDB")) { - - # NSRL - print -"

" - . "Exclude files in the NIST NSRL\n"; - } - - if (($Caseman::alert_db ne "") && (-e "$Caseman::alert_db")) { - print -"

" - . "Alert files that are found in the Alert Hash Database\n"; - } - - if (($Caseman::exclude_db ne "") && (-e "$Caseman::exclude_db")) { - print -"

" - . "Ignore files that are found in the Exclude Hash Database\n"; - } - - print "

\n

\n"; - - Print::print_html_footer(); - return; -} - -# Run sorter on the image -sub run { - Print::print_html_header("sorter - create"); - - my $sort_args = ""; - my $ext = 0; - my $cat = 0; - - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - Print::log_host_inv("Running 'sorter' on ($Caseman::vol2sname{$vol}"); - - $ext = 1 - if ( (exists $Args::args{'sorter_ext'}) - && ($Args::args{'sorter_ext'} == 1)); - $cat = 1 - if ( (exists $Args::args{'sorter_cat'}) - && ($Args::args{'sorter_cat'} == 1)); - - if (($cat == 0) && ($ext == 0)) { - print "At least one action must be selected\n" - . "

" - . "\"Ok\"\n"; - - return; - } - - # If both actions are wanted then no flags are needed - $sort_args .= "-e " if (($ext == 1) && ($cat == 0)); - $sort_args .= "-E " if (($ext == 0) && ($cat == 1)); - - my $sort_dir = get_sorter_dir(); - - if ($cat == 1) { - if ( (exists $Args::args{'sorter_img'}) - && ($Args::args{'sorter_img'} == 1)) - { - my $config = "$::TSKDIR/../share/tsk3/sorter/images.sort"; - - Print::print_err("images configuration file not found ($config)") - unless (-e "$config"); - - $sort_args .= "-C \'$config\' -s -U "; - - $sort_dir = get_sorter_graphics_dir(); - - } - else { - $sort_args .= "-s " - if ( (exists $Args::args{'sorter_save'}) - && ($Args::args{'sorter_save'} == 1)); - - $sort_args .= "-U " - if ( (exists $Args::args{'sorter_unk'}) - && ($Args::args{'sorter_unk'} == 1)); - } - } - - if ($::NSRLDB ne "") { - $sort_args .= "-n \'$::NSRLDB\' " - if ( (exists $Args::args{'sorter_nsrl'}) - && ($Args::args{'sorter_nsrl'} == 1)); - } - - if ($Caseman::alert_db ne "") { - $sort_args .= "-a \'$Caseman::alert_db\' " - if ( (exists $Args::args{'sorter_alert'}) - && ($Args::args{'sorter_alert'} == 1)); - } - - if ($Caseman::exclude_db ne "") { - $sort_args .= "-x \'$Caseman::exclude_db\' " - if ( (exists $Args::args{'sorter_exclude'}) - && ($Args::args{'sorter_exclude'} == 1)); - } - - unless (-d "$sort_dir") { - unless (mkdir "$sort_dir", $::MKDIR_MASK) { - Print::print_err("Error making $sort_dir"); - } - } - if (-e "$sort_dir/index.html") { - unlink("$sort_dir/index.html"); - } - - my $exec = -"-h -m '$mnt' -d '$sort_dir' -o $offset -i $imgtype -f $ftype $sort_args $img"; - - # print "Executing: sorter $exec

\n"; - - # Execute Sorter - my $hit_cnt = 0; - $SIG{ALRM} = sub { - if (($hit_cnt++ % 5) == 0) { - print "+"; - } - else { - print "-"; - } - alarm(5); - }; - alarm(5); - - local *OUT; - Exec::exec_pipe(*OUT, "LANG=C LC_ALL=C '$::TSKDIR/sorter' $exec"); - alarm(0); - $SIG{ALRM} = 'DEFAULT'; - - while ($_ = Exec::read_pipe_line(*OUT)) { - print "$_
\n"; - $hit_cnt = 0; - } - - close(OUT); - - if (-e "$sort_dir/index.html") { - print "

Output can be found by viewing:
" - . "  $sort_dir/index.html

\n"; - - # Print the index.html file from the output - print "


Results Summary

\n"; - open INDEX, "<$sort_dir/index.html" - or die "Can't open sorter index file ($sort_dir/index.html)"; - - while () { - next if ((/^/i) - || (/^<BODY><center><H2>/i)); - - # Extract out the symlinks to the categories - if (/^\s*<li><a href="\.\/[\w\.]+">([\w\s]+)<\/a> \((\d+)\)\s*$/i) { - print "<LI>$1 ($2)\n"; - } - - # Skip the link on the thumbnails link - elsif (/^\s*\(<a href=[\"\.\/\w]+>thumbnails<\/A>\)\s*$/) { - print "(thumbnails)\n"; - } - else { - print "$_"; - } - } - close(INDEX); - } - - Print::print_html_footer(); - return; -} - -# View Page -sub view { - Print::print_html_header(""); - print "<center><h3>File Type Sorting</h3>\n" - . "Autopsy does not currently support viewing the sorted files.<br>\n" - . "After sorting, you can view the results by opening the following file:<p>\n"; - print "<tt>" . get_sorter_dir() . "index.html</tt>"; - - Print::print_html_footer(); - return 0; -} - -# Blank Page -sub blank { - Print::print_html_header(""); - print "<center><h3>File Type Sorting</h3>\n" - . "In this mode, Autopsy will examine allocated and unallocated files<br> and " - . "sort them into categories and verify the extension.<p>This allows you to find a file based on" - . "its type and find \"hidden\" files.<p>\n" - . - - "WARNING: This can be a time intensive process.<br>\n"; - - Print::print_html_footer(); - return 0; -} - diff --git a/lib/Appview.pm b/lib/Appview.pm deleted file mode 100644 index 3a407fa2e1..0000000000 --- a/lib/Appview.pm +++ /dev/null @@ -1,291 +0,0 @@ -# -# View the application layer (HTML, picutures etc.) -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -# Updated 1/15 - -package Appview; - -$Appview::CELL_FRAME = 1; -$Appview::CELL_MENU = 2; -$Appview::CELL_CONT = 3; - -sub main { - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $Appview::CELL_FRAME - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - # Check Basic Args - Args::check_vol('vol'); - Args::check_meta('meta'); - Args::check_dir(); - Args::check_recmode(); - - if ($view == $Appview::CELL_FRAME) { - return cell_frame(); - } - elsif ($view == $Appview::CELL_CONT) { - return cell_content(); - } - elsif ($view == $Appview::CELL_MENU) { - return cell_menu(); - } - else { - Print::print_check_err("Invalid Application Viewing View"); - } -} - -######################################################################### -# -# CELL - Sanitized Environment -# - -my $CELL_MODE_SANIT = 1; -my $CELL_MODE_NORM = 2; - -sub cell_frame { - Print::print_html_header_frameset("Autopsy Cell"); - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $fname = "$mnt$Args::args{'dir'}"; - - print "<frameset rows=\"15%,85%\">\n"; - - # if a mode was not given, then choose the Sanitized by default - $Args::args{'cell_mode'} = $CELL_MODE_SANIT - unless ((exists $Args::args{'cell_mode'}) - && ($Args::args{'cell_mode'} =~ /^\d$/)); - - my $url = - "&$Args::baseargs&meta=$Args::enc_args{'meta'}" - . "&dir=$Args::enc_args{'dir'}&" - . "cell_mode=$Args::args{'cell_mode'}&recmode=$Args::args{'recmode'}"; - - print -"<frame src=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_MENU${url}\">\n" - . "<frame src=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_CONT${url}\">\n" - . "</frameset>\n"; - - Print::print_html_footer_frameset(); - return 0; -} - -# Print the menu on top. This allows one to export the file and change modes -sub cell_menu { - Args::check_cell_mode(); - - Print::print_html_header("Cell Header"); - - my $cell_mode = $Args::args{'cell_mode'}; - - my $url = - "&$Args::baseargs&meta=$Args::enc_args{'meta'}&" - . "dir=$Args::enc_args{'dir'}&recmode=$Args::enc_args{'recmode'}"; - - if ($cell_mode == $CELL_MODE_SANIT) { - - print <<EOF1; -<center> -This file is currently being viewed in a <b>sanitized environment</b><br> -HTML files have been edited to disable scripts and links. -The script contents will be shown as text.<br> -Pictures have been replaced by place holders<br> - -<table width=300 cellspacing=\"0\" cellpadding=\"2\"> -<tr> - <td align=center> - <a href=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_FRAME$url&cell_mode=$CELL_MODE_NORM\" - target=\"_top\"> - <img src=\"pict/sanit_b_norm.jpg\" alt=\"Normal\" border=\"0\"> - </a> - </td> -EOF1 - - } - - elsif ($cell_mode == $CELL_MODE_NORM) { - print <<EOF2; -<center> -This file is currently being viewed in a <b>normal environment</b><br> -HTML files are being viewed without modification.<br> - -<table width=300 cellspacing=\"0\" cellpadding=\"2\"> -<tr> - <td align=center> - <a href=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_FRAME&$url&cell_mode=$CELL_MODE_SANIT\" - target=\"_top\"> - <img src=\"pict/sanit_b_san.jpg\" alt=\"Sanitized\" border=\"0\"> - </a> - </td> -EOF2 - } - - # Export the file - print "<td align=center>\n" - . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::EXPORT&$url\">" - . "<img src=\"pict/but_export.jpg\" alt=\"export\" border=\"0\" " - . "width=123 height=20>" - . "</a></td></tr>\n"; - - print "<tr><td colspan=\"2\" align=\"center\">" - . "Deleted File Recovery Mode</td></tr>\n" - if ($Args::enc_args{'recmode'} == $File::REC_YES); - - print "</table>"; - - Print::print_html_footer(); - return; -} - -# Display safe and common things in the browser (pictures, basic html) -sub cell_content { - Args::check_meta('meta'); - Args::check_dir(); - Args::check_cell_mode(); - - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $fname = "$mnt$Args::args{'dir'}"; - - my $recflag = ""; - - $recflag = " -r " - if (Args::get_recmode() == $File::REC_YES); - - # identify what type it is - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - my $file_type = Exec::read_pipe_line(*OUT); - close(OUT); - - $file_type = "Error getting file type" - if ((!defined $file_type) || ($file_type eq "")); - - if ($file_type =~ /JPEG image data/) { - Print::log_host_inv("$vol: Viewing $fname ($meta) as JPEG"); - print "Content-type: image/jpeg$::HTTP_NL$::HTTP_NL"; - } - elsif ($file_type =~ /GIF image data/) { - Print::log_host_inv("$vol: Viewing $fname ($meta) as GIF"); - print "Content-type: image/gif$::HTTP_NL$::HTTP_NL"; - } - elsif ($file_type =~ /PNG image data/) { - Print::log_host_inv("$vol: Viewing $fname ($meta) as PNG"); - print "Content-type: image/png$::HTTP_NL$::HTTP_NL"; - } - elsif ($file_type =~ /PC bitmap data/) { - Print::log_host_inv("$vol: Viewing $fname ($meta) as BMP"); - print "Content-type: image/bmp$::HTTP_NL$::HTTP_NL"; - } - elsif ($file_type =~ /HTML document text/) { - Print::log_host_inv("$vol: Viewing $fname ($meta) as HTML"); - print "Content-type: text/html$::HTTP_NL$::HTTP_NL"; - } - else { - Print::log_host_inv("$vol: Unknown format of meta $meta "); - Print::print_check_err("Unknown File Type for Viewing: $file_type"); - } - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" - ); - - while ($_ = Exec::read_pipe_line(*OUT)) { - - # Parse out bad "stuff" - if ( ($file_type =~ /HTML document text/) - && ($Args::args{'cell_mode'} == $CELL_MODE_SANIT)) - { - $_ =~ s/\bsrc=/src=$::SANITIZE_TAG\?/ig; - $_ =~ s/\bhref=/href=$::SANITIZE_TAG\?/ig; - $_ =~ s/<script/<$::SANITIZE_TAG-script/ig; - $_ =~ s/\bbackground=/background=$::SANITIZE_TAG\?/ig; - } - print "$_"; - } - print "$::HTTP_NL$::HTTP_NL"; - close(OUT); - return 0; -} - -sub sanitize_pict { - 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); - print "$::HTTP_NL$::HTTP_NL"; - } - else { - $url =~ tr/\+/ /; - $url =~ s/%([a-f0-9][a-f0-9])/chr( hex( $1 ) )/eig; - - Print::print_html_header("Denied"); - print "<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::print_html_footer(); - } - - exit(0); -} - diff --git a/lib/Args.pm b/lib/Args.pm deleted file mode 100644 index 705cc89a39..0000000000 --- a/lib/Args.pm +++ /dev/null @@ -1,927 +0,0 @@ -# -# Functions to check and get the arguments from URL -# -# ver 2.00+ -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2003-2004 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 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. - -package Args; - -# Parse the argument string into the args hash -sub parse_args { - my $lcl_args = shift; - foreach my $nam_val (split(/&/, $lcl_args)) { - my ($name, $value) = split(/=/, $nam_val); - if (defined $value) { - my $dec_name = url_decode($name); - $Args::enc_args{$dec_name} = $value; - $Args::args{$dec_name} = url_decode($value); - } - } -} - -sub url_encode { - my $text = shift; - $text =~ s/([^a-z0-9_.!~*'() -])/sprintf "%%%02X", ord($1)/eig; - $text =~ tr/ /+/; - return $text; -} - -sub url_decode { - my $text = shift; - $text =~ tr/\+/ /; - $text =~ s/%([a-f0-9][a-f0-9])/chr( hex( $1 ) )/eig; - return $text; -} - -# This assumes that the checking of the types has been done and this just -# makes a string of the key values if they exist -# -# case -# host -# img - -# Must add & after -sub make_baseargs { - $Args::baseargs = ""; - - # The standard case, host, and investigator - $Args::baseargs .= "case=$Args::enc_args{'case'}&" - if ((exists $Args::enc_args{'case'}) && ($Args::enc_args{'case'} ne "")); - $Args::baseargs .= "host=$Args::enc_args{'host'}&" - if ((exists $Args::enc_args{'host'}) && ($Args::enc_args{'host'} ne "")); - $Args::baseargs .= "inv=$Args::enc_args{'inv'}&" - if ((exists $Args::enc_args{'inv'}) && ($Args::enc_args{'inv'} ne "")); - - $Args::baseargs_novol = $Args::baseargs; - - # Add the image, file system type, and mount point - $Args::baseargs .= "vol=$Args::enc_args{'vol'}&" - if ((exists $Args::enc_args{'vol'}) && ($Args::enc_args{'vol'} ne "")); - - # remove the final '&' - $Args::baseargs_novol = $1 if ($Args::baseargs_novol =~ /^(.*?)&$/); - $Args::baseargs = $1 if ($Args::baseargs =~ /^(.*?)&$/); - - return; -} - -# Does not do mnt or img -sub make_hidden { - my $str = ""; - - $str .= - "<input type=\"hidden\" name=\"host\" value=\"$Args::args{'host'}\">\n" - if ((exists $Args::args{'host'}) && ($Args::args{'host'} ne "")); - - $str .= - "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" - if ((exists $Args::args{'case'}) && ($Args::args{'case'} ne "")); - - $str .= - "<input type=\"hidden\" name=\"inv\" value=\"$Args::args{'inv'}\">\n" - if ((exists $Args::args{'inv'}) && ($Args::args{'inv'} ne "")); - - return $str; -} - -############################### -# block -############################### -sub check_block { - if ((!exists $Args::args{'block'}) || ($Args::args{'block'} !~ /^\d+$/)) { - Print::print_check_err( - "Invalid block argument (positive numbers only)"); - } - return 0; -} - -sub get_block { - if ($Args::args{'block'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid Block"); -} - -############################### -# body -############################### - -sub check_body { - unless (exists $Args::args{'body'}) { - Print::print_check_err("Missing body argument"); - } - unless ($Args::args{'body'} =~ /^$::REG_VNAME$/o) { - Print::print_check_err( - "Invalid body value (only letters, " . "numbers,-,., and _)"); - } - return 0; -} - -sub get_body { - if ($Args::args{'body'} =~ /^($::REG_VNAME)$/o) { - return $1; - } - Print::print_err("Invalid Body"); -} - -################################ -# Case name -################################ - -sub check_case { - unless (exists $Args::args{'case'}) { - Print::print_check_err("Missing case argument"); - } - unless ($Args::args{'case'} =~ /^$::REG_CASE$/o) { - Print::print_check_err( - "Invalid case value (letters, num, and symbols only"); - } - return 0; -} - -sub get_case { - if ($Args::args{'case'} =~ /^($::REG_CASE)$/o) { - return $1; - } - Print::print_err("Invalid Case Name"); -} - -############################### -# cell_mode -############################### -sub check_cell_mode { - if ( (!exists $Args::args{'cell_mode'}) - || ($Args::args{'cell_mode'} !~ /^\d$/o)) - { - Print::print_check_err( - "Invalid cell_mode argument (numbers >= 0 only)"); - } - return 0; -} - -################################ -# dir -################################ -sub check_dir { - if ( (!exists $Args::args{'dir'}) - || ($Args::args{'dir'} =~ /\/\.\.\//) - || ($Args::args{'dir'} =~ /\;/)) - { - Print::print_check_err("Invalid dir argument (valid file path only)"); - } - return 0; -} - -sub get_dir { - if ($Args::args{'dir'} =~ /([^;]*)/o) { - my $d = $1; - - # Remove double slashes - $d =~ s/\/\//\//g; - return $d; - } - Print::print_err("Invalid Directory"); -} - -############################### -# dirmode -############################### -sub check_dirmode { - if ((!exists $Args::args{'dirmode'}) || ($Args::args{'dirmode'} !~ /^\d+$/)) - { - Print::print_check_err( - "Invalid dirmode argument (positive numbers only)"); - } - return 0; -} - -sub get_dirmode { - if ($Args::args{'dirmode'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid dirmode"); -} - -################################ -# do_md5 -################################ -sub check_do_md5 { - if ((!exists $Args::args{'do_md5'}) || ($Args::args{'do_md5'} !~ /^\d+$/)) { - Print::print_check_err("Missing do_md5 argument"); - } - return 0; -} - -sub get_do_md5 { - if ($Args::args{'do_md5'} =~ /^\s*(\d+)$/) { - return $1; - } - Print::print_err("Invalid MD5 Flag"); -} - -################################ -# fname -################################ - -sub check_fname { - unless (exists $Args::args{'fname'}) { - Print::print_check_err("Missing fname argument"); - } - unless ($Args::args{'fname'} =~ /^$::REG_FNAME$/o) { - Print::print_check_err( - "Invalid fname value (only letters, " . "numbers,-,., and _)"); - } - return 0; -} - -sub get_fname { - if ($Args::args{'fname'} =~ /^($::REG_FNAME)$/o) { - return "$::host_dir" . "$::DATADIR/$1"; - } - Print::print_err("Invalid File Name"); -} - -################################ -# fname_mode -################################ -sub check_fname_mode { - if (!exists $Args::args{'fname_mode'}) { - Print::print_check_err("Missing fname_mode argument"); - } - unless ($Args::args{'fname_mode'} =~ /^\d+$/) { - Print::print_check_err("invalid mode: numbers only"); - } - return 0; -} - -################################ -# fname_rel -# Return the relative fname -################################ -sub get_fname_rel { - if ($Args::args{'fname'} =~ /^($::REG_FNAME)$/o) { - return "$::DATADIR/$1"; - } - Print::print_err("Invalid Relative File Name"); -} - -############################### -# force -############################### -sub get_force { - if ($Args::args{'force'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid Force Flag"); -} - -################################ -# ftype -################################ -sub get_ftype_blah { - if (exists $Args::args{'ftype'}) { - if ($Args::args{'ftype'} =~ /^($::REG_FTYPE)$/o) { - return $1; - } - } - if ( (exists $Args::args{'img'}) - && (exists $Caseman::vol2ftype{$Args::args{'img'}})) - { - return $Caseman::vol2ftype{$Args::args{'img'}}; - } - Print::print_err("Missing ftype value"); -} - -sub check_ftype_blah { - unless ( - ( - (exists $Args::args{'img'}) - && (exists $Caseman::vol2ftype{$Args::args{'img'}}) - && ($Caseman::vol2ftype{$Args::args{'img'}} =~ /^$::REG_FTYPE$/o) - ) - || ( (exists $Args::args{'ftype'}) - && ($Args::args{'ftype'} =~ /^$::REG_FTYPE$/o)) - ) - { - Print::print_check_err("Missing or invalid ftype value"); - } - return 0; -} - -################################ -# host -# Host for the case -################################ - -sub check_host { - unless (exists $Args::args{'host'}) { - Print::print_check_err("Missing host argument"); - } - unless ($Args::args{'host'} =~ /^$::REG_HOST$/o) { - Print::print_check_err("Invalid host value"); - } - return 0; -} - -sub get_host { - if ($Args::args{'host'} =~ /^($::REG_HOST)$/o) { - return $1; - } - Print::print_err("Invalid Host"); -} - -################################ -# htype -################################ -sub check_htype { - if ((!exists $Args::args{'htype'}) || ($Args::args{'htype'} !~ /^\d+$/)) { - Print::print_check_err( - "Invalid htype argument (positive numbers only)"); - } - return 0; -} - -sub get_htype { - if ($Args::args{'htype'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid htype"); -} - -############################### -# ifind -# ifind is optional and by default is 0 if not given -############################### -sub get_ifind { - if (!exists $Args::args{'ifind'}) { - return 0; - } - elsif ($Args::args{'ifind'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid ifind flag"); -} - -############################### -# img_path is used when adding images - it is the full path to the -# non-evidence locker copy of the image -############################### - -sub check_img_path { - if (!exists $Args::args{'img_path'}) { - Print::print_check_err("Missing image (img_path) argument"); - } - elsif ($Args::args{'img_path'} =~ /^$::REG_IMG_PATH$/o) { - - # Check for its actual existence - - Print::print_check_err("Image not found at $Args::args{'img_path'}") - unless ( - (-e "$Args::args{'img_path'}") - || ( (-l "$Args::args{'img_path'}") - && (-e readlink "$::host_dir" . "$Args::args{$img}")) - ); - } - else { - Print::print_check_err("Invalid image path (only letters, " - . "numbers,-,.,_/ and start with /) [$Args::args{'img_path'}]"); - } - - return 0; -} - -sub get_img_path { - if ($Args::args{'img_path'} =~ /^($::REG_IMG_PATH)$/o) { - return "$1"; - } - Print::print_err("Invalid Image Path"); -} - -sub check_img_path_wild { - if (!exists $Args::args{'img_path'}) { - Print::print_check_err("Missing wild image (img_path) argument"); - } - elsif ($Args::args{'img_path'} !~ /^$::REG_IMG_PATH_WILD$/o) { - - # IF there is extra white space then remove it and move on - if ($Args::args{'img_path'} =~ /^\s*($::REG_IMG_PATH_WILD)\s*$/o) { - $Args::args{'img_path'} = $1; - return 0; - } - else { - Print::print_check_err("Invalid wild image (img_path) argument"); - } - } - - return 0; -} - -sub get_img_path_wild { - if ($Args::args{'img_path'} =~ /^($::REG_IMG_PATH_WILD)$/o) { - return "$1"; - } - Print::print_err("Invalid Image Path"); -} - -############################### -# meta -############################### - -sub check_meta { - my $meta = shift; - if ( (!exists $Args::args{$meta}) - || ($Args::args{$meta} !~ /^$::REG_META$/o)) - { - Print::print_check_err( - "Invalid meta address ($meta) argument (numbers >= 0 only)"); - } - return 0; -} - -sub get_meta { - my $meta = shift; - if ($Args::args{$meta} =~ /^($::REG_META)$/o) { - return $1; - } - Print::print_err("Invalid Meta Address"); -} - -################################ -# inv -# Investigator -################################ - -sub check_inv { - unless (exists $Args::args{'inv'}) { - Print::print_check_err("Missing inv argument"); - } - unless ($Args::args{'inv'} =~ /^$::REG_INVESTIG$/o) { - Print::print_check_err( - "Invalid inv value (letters, num, and symbols only"); - } - return 0; -} - -sub get_inv { - if ($Args::args{'inv'} =~ /^($::REG_INVESTIG)$/o) { - return $1; - } - Print::print_err("Invalid Investigator"); -} - -############################### -# len -############################### -sub check_len { - if ( (!exists $Args::args{'len'}) - || ($Args::args{'len'} !~ /^\d+$/) - || ($Args::args{'len'} == 0)) - { - Print::print_check_err("Invalid len argument (positive numbers only)"); - } - return 0; -} - -sub get_len { - if ((exists $Args::args{'len'}) && ($Args::args{'len'} =~ /^(\d+)$/)) { - return $1; - } - - # return the default len of 1 if it is not defined - return 1; -} - -############################### -# min -############################### -sub get_min { - if ($Args::args{'min'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid Minute"); -} - -################################ -# module -################################ -sub check_mod { - if ((!exists $Args::args{'mod'}) || ($Args::args{'mod'} !~ /^\d+$/)) { - Print::print_check_err( - "Invalid Module argument (positive numbers only)"); - } - return 0; -} - -sub get_mod { - if ($Args::args{'mod'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid Module"); -} - -################################ -# mnt -############################### - -sub check_mnt { - my $ftype = Args::get_ftype(); - if (($ftype eq "blkls") || ($ftype eq "swap") || ($ftype eq "raw")) { - $Args::args{'mnt'} = $ftype; - $Args::enc_args{'mnt'} = $ftype; - } - elsif (!exists $Args::args{'mnt'}) { - - # Look it up if it is not found - if (exists $Args::args{'img'}) { - unless (exists $Caseman::vol2mnt{$Args::args{'img'}}) { - Print::print_check_err( - "Mounting point not found: $Args::args{'img'}"); - } - my $mnt = $Caseman::vol2mnt{$Args::args{'img'}}; - $Args::args{'mnt'} = $mnt; - $Args::enc_args{'mnt'} = Args::url_encode($mnt); - } - else { - Print::print_check_err("Mounting point not found"); - } - } - if ($Args::args{'mnt'} =~ /\/\.\.\//) { - Print::print_check_err( - "Invalid mount point argument (valid file path only)"); - } - unless ($Args::args{'mnt'} =~ /^$::REG_MNT$/o) { - Print::print_check_err( - "Invalid mount point argument (valid file path only)"); - } - return 0; -} - -sub get_mnt { - if ((exists $Args::args{'mnt'}) && ($Args::args{'mnt'} =~ /($::REG_MNT)/o)) - { - return $1; - } - Print::print_err("Invalid Mounting Point"); -} - -################################ -# note -################################ -sub check_note { - if (!exists $Args::args{'note'}) { - Print::print_check_err("Missing note argument"); - } - return 0; -} - -################# -# num_img - adding disk images - -sub check_num_img { - if ((!exists $Args::args{'num_img'}) || ($Args::args{'num_img'} !~ /^\d+$/)) - { - Print::print_check_err( - "Invalid num_img argument (positive numbers only)"); - } - return 0; -} - -sub get_num_img { - if ($Args::args{'num_img'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid num_img"); -} - -############################### -# recmode -############################### -sub check_recmode { - if ((!exists $Args::args{'recmode'}) || ($Args::args{'recmode'} !~ /^\d+$/)) - { - Print::print_check_err( - "Invalid recmode argument (positive numbers only)"); - } - return 0; -} - -sub get_recmode { - if ($Args::args{'recmode'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid recmode"); -} - -################################ -# srchidx -# -# Index for previous keyword search -############################### -sub check_srchidx { - if ((!exists $Args::args{'srchidx'}) || ($Args::args{'srchidx'} !~ /^\d+$/)) - { - Print::print_check_err( - "Invalid srchidx argument (positive numbers only)"); - } - return 0; -} - -############################### -# sort -############################### -sub check_sort { - if ((!exists $Args::args{'sort'}) || ($Args::args{'sort'} !~ /^\d+$/)) { - Print::print_check_err("Invalid sort argument (positive numbers only)"); - } - return 0; -} - -sub get_sort { - if ($Args::args{'sort'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid sort flag"); -} - -################################ -# st_mon -################################ -sub check_st_mon { - if ( (exists $Args::args{'st_mon'}) - && ($Args::args{'st_mon'} =~ /^(\d\d?)$/)) - { - if (($1 < 1) || ($1 > 12)) { - print("Invalid start month\n"); - return 1; - } - } - else { - print("Invalid start month\n"); - return 1; - } -} - -sub get_st_mon { - if ($Args::args{'st_mon'} =~ /^(\d\d?)$/) { - return $1; - } - Print::print_err("Invalid Month"); -} - -################################ -# st_year -################################ -sub check_st_year { - if ( (exists $Args::args{'st_year'}) - && ($Args::args{'st_year'} =~ /^(\d\d\d\d?)$/)) - { - if (($1 < 1970) || ($1 > 2020)) { - print("Invalid start year\n"); - return 1; - } - } - else { - print("Invalid start year\n"); - return 1; - } -} - -sub get_st_year { - if ($Args::args{'st_year'} =~ /^(\d\d\d\d)$/) { - return $1; - } - Print::print_err("Invalid Year"); -} - -################################ -# str -# search string -################################ -# This should be made more flexible -sub check_str { - if (!exists $Args::args{'str'}) { - Print::print_check_err("Missing string argument"); - } - return 0; -} - -sub get_str { - if ($Args::args{'str'} =~ /^\s*(.*)$/) { - return $1; - } - Print::print_err("Invalid String"); -} - -############################### -# submod -# Used by the tab module to identify the actual module -############################### -sub check_submod { - if ((!exists $Args::args{'submod'}) || ($Args::args{'submod'} !~ /^\d+$/)) { - Print::print_check_err( - "Invalid sub-mode argument (positive numbers only)"); - } - return 0; -} - -sub get_submod { - if ($Args::args{'submod'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid sub-mode"); -} - -################################ -# tl -############################### -sub check_tl { - if ((!exists $Args::args{'tl'}) || ($Args::args{'tl'} !~ /^$::REG_VNAME$/)) - { - Print::print_check_err( - "Invalid timeline argument (positive numbers only)"); - } - return 0; -} - -sub get_tl { - if ($Args::args{'tl'} =~ /^($::REG_VNAME)$/o) { - return $1; - } - Print::print_err("Invalid Timeline"); -} - -################################ -# ts -# time skew -################################ -sub check_ts { - if ((!exists $Args::args{'ts'}) || ($Args::args{'ts'} !~ /^$::REG_SKEW$/o)) - { - Print::print_check_err("Missing time skew argument"); - } - return 0; -} - -sub get_ts { - if ($Args::args{'ts'} =~ /^\s*($::REG_SKEW)$/o) { - return $1; - } - Print::print_err("Invalid Time Skew"); -} - -################################ -# tz -# timezone -################################ -sub check_tz { - if ( (!exists $Args::args{'tz'}) - || ($Args::args{'tz'} !~ /^$::REG_ZONE_ARGS$/o)) - { - Print::print_check_err("Missing time zone argument"); - } - return 0; -} - -sub get_tz { - if ($Args::args{'tz'} =~ /^($::REG_ZONE_ARGS)$/o) { - return $1; - } - Print::print_err("Invalid Timezone"); -} - -################################ -# unitsize -################################ -sub get_unitsize { - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $blkcat_out; - - if ($ftype eq 'blkls') { - if (exists $Caseman::mod2vol{$vol}) { - my $orig = $Caseman::mod2vol{$vol}; - my $img = $Caseman::vol2path{$orig}; - my $offset = $Caseman::vol2start{$orig}; - my $imgtype = $Caseman::vol2itype{$orig}; - - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $Caseman::vol2ftype{$orig} -s -o $offset -i $imgtype $img" - ); - $blkcat_out = <OUT>; - close(OUT); - } - - # We don't have the original image, so just set the size to 512 - else { - return 512; - } - } - elsif ($ftype eq 'swap') { - return 4096; - } - elsif ($ftype eq 'raw') { - return 512; - } - elsif ($Caseman::vol2cat{$vol} eq 'disk') { - return 512; - } - else { - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkcat' -f $ftype -s -o $offset -i $imgtype $img"); - $blkcat_out = <OUT>; - close(OUT); - } - $blkcat_out = "Error getting unit size" - if ((!defined $blkcat_out) || ($blkcat_out eq "")); - - if ($blkcat_out =~ /(\d+): Size of Addressable Unit/) { - return $1; - } - else { - Print::print_err("Error identifying block size (blkcat -s output)\n" - . "$blkcat_out\n"); - } -} - -################################ -# View - subset of module -################################ -sub check_view { - if ((!exists $Args::args{'view'}) || ($Args::args{'view'} !~ /^\d+$/)) { - Print::print_check_err("Invalid View argument (positive numbers only)"); - } - return 0; -} - -sub get_view { - if ($Args::args{'view'} =~ /^(\d+)$/) { - return $1; - } - Print::print_err("Invalid View"); -} - -############################### -# We don't allow much for the volume because this is an argument to -# the TSK programs. We keep these files only in one -# directory and for easy/simple security only allow basic names -# Symbolic links are allowed if these simple names are not desired -# -# Allowed values are A-Za-z0-9_-. -# -# The argument is the name of the image -############################### - -sub check_vol { - my $vol = shift; - if ((!exists $Args::args{$vol}) || ($Args::args{$vol} !~ /^$::REG_VNAME$/)) - { - Print::print_check_err( - "Invalid volume argument (name and number only)"); - } - return 0; -} - -sub get_vol { - my $vol = shift; - if ($Args::args{$vol} =~ /^($::REG_VNAME)$/) { - return $1; - } - Print::print_err("Invalid volume ($vol)"); -} - -1; diff --git a/lib/Caseman.pm b/lib/Caseman.pm deleted file mode 100644 index a34db68087..0000000000 --- a/lib/Caseman.pm +++ /dev/null @@ -1,4161 +0,0 @@ -# -# Case Management methods, including the windows and functions to read the -# config files -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -package Caseman; - -# If the order of these views are changed, then the order of the main -# function may have to be as well - -# Case Views -$Caseman::CASE_NEW = 1; -$Caseman::CASE_NEW_DOIT = 2; -$Caseman::CASE_OPEN = 3; -$Caseman::CASE_OPEN_LOG = 4; -$Caseman::CASE_DETAILS = 5; - -# $Caseman::CASE_DEL = 6; -my $CASE_MAX = 5; - -# Host Views -$Caseman::HOST_ADD = 7; -$Caseman::HOST_ADD_DOIT = 8; -$Caseman::HOST_OPEN = 9; -$Caseman::HOST_OPEN_LOG = 10; -$Caseman::HOST_DETAILS = 11; - -# $Caseman::HOST_DEL = 12; -my $HOST_MAX = 11; - -# Image Views -$Caseman::IMG_ADD = 13; -$Caseman::IMG_ADD_PREP = 14; -$Caseman::IMG_ADD_DOIT = 15; -$Caseman::VOL_OPEN = 16; -$Caseman::VOL_OPEN_LOG = 17; -$Caseman::VOL_DETAILS = 18; -$Caseman::IMG_DEL = 19; -$Caseman::VOL_MAKESTR = 20; -$Caseman::VOL_MAKEBLKLS = 21; -my $IMG_MAX = 21; - -# Module Variables -# %vol2par - Volume to parent volume (vol to img, str to vol) -# %vol2start - Starting sector of volume in image -# %vol2end - ending sector of volume in image -# %vol2cat - The big picture type of volume (part, disk, strings, blkls) -# %vol2ftype - The file system type (fat, dos, ntfs etc.) -# %vol2itype - The image file type (could be for a parent image) -# %vol2dtype- the disk type -# %mod2vol; # Mapping for image, given the strings or blkls -# %vol2mnt; # Mapping for mount point, given the vol name -# %vol2str; # Mapping for ASCII strings file, given the vol name -# %vol2uni; # Mapping for Unicode strings file, given the vol name -# %vol2blkls; # Mapping for blkls file, given the vol name -# %vol2path - full file path of volume -# %vol2sname - short name of volume - -sub main { - - # By default, show the case open window - $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::CASE_OPEN - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - # The only live function is for the open img - if ($::LIVE == 1) { - Args::check_inv(); - if ($view == $Caseman::VOL_OPEN) { - return vol_open(); - } - - Args::check_vol('vol'); - - # Args::check_ftype(); - # Args::check_mnt(); - - if ($view == $Caseman::VOL_OPEN_LOG) { - return vol_open_log(); - } - else { - Print::print_check_err( - "Invalid Live Analysis Case Management View"); - } - return 0; - } - - # Case functions - if ($view <= $CASE_MAX) { - if ($view == $Caseman::CASE_OPEN) { - return case_open(); - } - elsif ($view == $Caseman::CASE_NEW) { - return case_new(); - } - - Args::check_case(); - $::case_dir = "$::LOCKDIR/" . Args::get_case() . "/"; - $::case_dir =~ s/\/\//\//g; - - if ($view == $Caseman::CASE_OPEN_LOG) { - return case_open_log(); - } - elsif ($view == $Caseman::CASE_NEW_DOIT) { - return case_new_doit(); - } - elsif ($view == $Caseman::CASE_DETAILS) { - return case_details(); - } - } - - Args::check_case(); - $::case_dir = "$::LOCKDIR/" . Args::get_case() . "/"; - $::case_dir =~ s/\/\//\//g; - - # Host functions - if ($view <= $HOST_MAX) { - if ($view == $Caseman::HOST_OPEN) { - return host_open(); - } - elsif ($view == $Caseman::HOST_ADD) { - return host_add(); - } - - Args::check_host(); - $::host_dir = "$::case_dir" . Args::get_host() . "/"; - $::host_dir =~ s/\/\//\//g; - if ($view == $Caseman::HOST_ADD_DOIT) { - return host_add_doit(); - } - - Caseman::read_host_config(); - if ($view == $Caseman::HOST_OPEN_LOG) { - return host_open_log(); - } - elsif ($view == $Caseman::HOST_DETAILS) { - return host_details(); - } - } - - Args::check_host(); - $::host_dir = "$::case_dir" . Args::get_host() . "/"; - $::host_dir =~ s/\/\//\//g; - Caseman::read_host_config(); - Args::check_inv(); - - if ($view <= $IMG_MAX) { - if ($view == $Caseman::VOL_OPEN) { - return vol_open(); - } - elsif ($view == $Caseman::IMG_ADD) { - return img_add(); - } - elsif ($view == $Caseman::IMG_ADD_PREP) { - return img_add_prep(); - } - elsif ($view == $Caseman::IMG_ADD_DOIT) { - return img_add_doit(); - } - - Args::check_vol('vol'); - - if ($view == $Caseman::VOL_OPEN_LOG) { - return vol_open_log(); - } - elsif ($view == $Caseman::VOL_DETAILS) { - return vol_details(); - } - - # elsif ($view == $Caseman::IMG_DEL) { - # return img_del(); - # } - elsif ($view == $Caseman::VOL_MAKESTR) { - return vol_makestr(); - } - elsif ($view == $Caseman::VOL_MAKEBLKLS) { - return vol_makeblkls(); - } - } - - Print::print_check_err("Invalid Case Management View"); -} - -#################################################################### -# General menu Functions - -sub print_menu_tabs { - - if ($::LIVE == 1) { - print "<h2>Live Analysis Mode</h2>\n"; - } - - print "<table width=\"600\" height=\"60\" background=\"$::YEL_PIX\" " - . "border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tr>\n" - . "<td align=\"center\" width=\"200\">"; - - my $view = Args::get_view(); - - # Case Gallery Tab - if ($view == $Caseman::CASE_OPEN) { - print "<img border=0 src=\"pict/menu_t_cg_cur.jpg\" " - . "width=200 height=65 alt=\"Case Gallery (Current Mode)\">\n"; - } - elsif ($::LIVE == 1) { - print "<img border=0 src=\"pict/menu_t_cg_org.jpg\" " - . "width=200 height=65 alt=\"Case Gallery\">\n"; - } - else { - print "<a href=\"$::PROGNAME?" - . "mod=$::MOD_CASEMAN&view=$Caseman::CASE_OPEN\">" - . "<img border=0 src=\"pict/menu_t_cg_link.jpg\" " - . "width=200 height=65 alt=\"Case Gallery\"></a>\n"; - } - print "</td>\n" . "<td align=\"center\" width=\"200\">"; - - # Host Gallery Tab - # Current - if ($view == $Caseman::HOST_OPEN) { - print "<img border=0 src=\"pict/menu_t_hg_cur.jpg\" " - . "width=200 height=65 alt=\"Host Gallery (Current Mode)\">\n"; - } - - # Link - elsif (($view == $Caseman::VOL_OPEN) && ($::LIVE == 0)) { - print "<a href=\"$::PROGNAME?" - . "mod=$::MOD_CASEMAN&view=$Caseman::HOST_OPEN" - . "&case=$Args::args{'case'}\">" - . "<img border=0 src=\"pict/menu_t_hg_link.jpg\" " - . "width=200 height=65 alt=\"Host Gallery\"></a>\n"; - } - - # Non-link - else { - print "<img border=0 src=\"pict/menu_t_hg_org.jpg\" " - . "width=200 height=65 alt=\"Host Gallery (Not Available)\">\n"; - } - - print "</td>\n" . "<td align=\"center\" width=\"200\">"; - - # Host Manager Tab - # Current - if ($view == $Caseman::VOL_OPEN) { - print "<img border=0 src=\"pict/menu_t_hm_cur.jpg\" " - . "width=200 height=65 alt=\"Host Manager (Current Mode)\">\n"; - } - - # non-link - else { - print "<img border=0 src=\"pict/menu_t_hm_org.jpg\" " - . "width=200 height=65 alt=\"Host Manager (Not Available)\">\n"; - } - - print "</td>\n</tr>\n" . "</table>\n"; -} - -#################################################################### -# Case Functions - -# if no args are passed, return case config using args{'case'}, -# else use the case value passed -# -# Case config: -# In case directory with case_name.case -sub case_config_fname { - if (scalar(@_) == 1) { - my $c = shift; - return "$::LOCKDIR/" . "$c/case.aut"; - } - else { - return "$::LOCKDIR/" . "$Args::args{'case'}/case.aut"; - } -} - -# Read case config and save it to $Caseman::cvals -sub read_case_config { - return if ($::LIVE == 1); - - my $case; - - if (scalar(@_) == 1) { - $case = shift; - } - else { - $case = Args::get_case(); - } - - my $fname = case_config_fname($case); - - %Caseman::cvals = (); - - open CONFIG, "<$fname" - or die "Can't open case config file ($fname)"; - - while (<CONFIG>) { - next if ((/^\#/) || (/^\s+$/)); - s/^\s+//; - s/\s+$//; - $Caseman::cvals{$1} = Print::html_encode($2) if (/^(\S+)\s+(.*)$/); - } - close(CONFIG); - - $Caseman::cvals{'desc'} = "None Provided" - unless (exists $Caseman::cvals{'desc'}); - - $Caseman::cvals{'created'} = "unknown" - unless (exists $Caseman::cvals{'created'}); -} - -sub case_new { - Print::print_html_header("Create A New Case"); - - print <<EOF; -<br> -<br> -<center> -<img src=\"pict/menu_h_cnew.jpg\" alt=\"New Case\"> -<br><br><br> - -<table width=\"600\" background=\"$::YEL_PIX\" cellspacing=\"0\" - cellpadding=\"2\" border=0> -<form action=\"$::PROGNAME\" method=\"get\"> -<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> -<input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_NEW_DOIT\"> -<tr> - <td colspan=3 align=left> - 1. <b>Case Name:</b> The name of this investigation. It can contain only letters, numbers, and symbols. - </td> -</tr> -<tr> - <td>  </td> - <td align=left colspan=2><input type=\"text\" name=\"case\"></td> -</tr> - -<tr><td colspan=3> </td></tr> - -<tr> - <td colspan=3 align=left> - 2. <b>Description:</b> An optional, one line description of this case. - </td> -</tr> -<tr> - <td>  </td> - <td align=left colspan=2><input type=\"text\" name=\"desc\" size=32 maxlength=32></td> -</tr> - -<tr><td colspan=3> </td></tr> - -<tr> - <td colspan=3 align=left> - 3. <b>Investigator Names:</b> The optional names (with no spaces) of the investigators for this case. - </td> -</tr> -<tr> - <td> </td> - <td align=left><tt>a.</tt> <input type=\"text\" name=\"inv1\"></td> - <td align=left><tt>b.</tt> <input type=\"text\" name=\"inv2\"></td> -</tr> -<tr> - <td> </td> - <td align=left><tt>c.</tt> <input type=\"text\" name=\"inv3\"></td> - <td align=left><tt>d.</tt> <input type=\"text\" name=\"inv4\"></td> -</tr> -<tr> - <td> </td> - <td align=left><tt>e.</tt> <input type=\"text\" name=\"inv5\"></td> - <td align=left><tt>f.</tt> <input type=\"text\" name=\"inv6\"></td> -</tr> -<tr> - <td> </td> - <td align=left><tt>g.</tt> <input type=\"text\" name=\"inv7\"></td> - <td align=left><tt>h.</tt> <input type=\"text\" name=\"inv8\"></td> -</tr> -<tr> - <td> </td> - <td align=left><tt>i.</tt> <input type=\"text\" name=\"inv9\"></td> - <td align=left><tt>j.</tt> <input type=\"text\" name=\"inv10\"></td> -</tr> -</table> - -<br><br> -<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\"> -<tr> - <td align=center> - <input type=\"image\" src=\"pict/menu_b_cnew.jpg\" - alt=\"Create Case\" width=\"176\" height=20 border=0> - </td> -</form> - <td align=center> - <form action=\"$::PROGNAME\" method=\"get\"> - <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> - <input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_OPEN\"> - <input type=\"image\" src=\"pict/menu_b_cancel.jpg\" - alt=\"Cancel\" width=\"167\" height=20 border=0> - </form> - </td> - <td align=center><a href=\"$::HELP_URL\" - target=\"_blank\"> - <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" - width=\"167\" height=20 border=0></a> - </td> -</tr> -</table> -EOF - - Print::print_html_footer(); - return; -} - -# Create the directory and case configuration file -# Gets the input from CASE_NEW -sub case_new_doit { - Print::print_html_header("Creating Case: $Args::args{'case'}"); - my $case = $Args::args{'case'}; - - print "<h3>Creating Case: <tt>$case</tt></h3>\n"; - - # Make the directory - if (-d "$::case_dir") { - - # we can't send all of this to print_err, bc it doesn't want HTML - print "Error: $::case_dir already exists<br>" - . "Please remove the directory and its contents and try again" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::CASE_OPEN\">" - . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=\"43\" height=20 border=\"0\"></a>\n"; - Print::print_err("\n"); - } - - unless (mkdir "$::case_dir", $::MKDIR_MASK) { - Print::print_err("Error making directory $::case_dir: $!"); - } - - print "Case directory (<tt>$::case_dir</tt>) created<br>\n"; - Print::log_case_info("Case $case created"); - - my $fname = Caseman::case_config_fname(); - - open CASE_CONFIG, ">$fname" or die "Can't open case config: $fname"; - - print CASE_CONFIG "# Autopsy case config file\n" - . "# Case: $case\n\n" - . "created " - . localtime() . "\n"; - - if ((exists $Args::args{'desc'}) && ($Args::args{'desc'} ne "")) { - Print::print_err( - "Invalid Description\n" . "Use the browser's back button to fix") - if ($Args::args{'desc'} =~ /\n/); - - print CASE_CONFIG "desc $Args::args{'desc'}\n"; - } - print CASE_CONFIG "images $::IMGDIR\n"; - print CASE_CONFIG "data $::DATADIR\n"; - print CASE_CONFIG "log $::LOGDIR\n"; - print CASE_CONFIG "reports $::REPDIR\n"; - - close CASE_CONFIG; - print "Configuration file (<tt>$fname</tt>) created<br>\n"; - - my $iname = investig_fname(); - open INVES, ">>$iname" or die "Can't open investigators file: $iname"; - - my @invs; - if ( (exists $Args::args{'inv1'}) - && ($Args::args{'inv1'} ne "") - && ($Args::args{'inv1'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv2'}) - && ($Args::args{'inv2'} ne "") - && ($Args::args{'inv2'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv3'}) - && ($Args::args{'inv3'} ne "") - && ($Args::args{'inv3'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv4'}) - && ($Args::args{'inv4'} ne "") - && ($Args::args{'inv4'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv5'}) - && ($Args::args{'inv5'} ne "") - && ($Args::args{'inv5'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv6'}) - && ($Args::args{'inv6'} ne "") - && ($Args::args{'inv6'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv7'}) - && ($Args::args{'inv7'} ne "") - && ($Args::args{'inv7'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv8'}) - && ($Args::args{'inv8'} ne "") - && ($Args::args{'inv8'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv9'}) - && ($Args::args{'inv9'} ne "") - && ($Args::args{'inv9'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - if ( (exists $Args::args{'inv10'}) - && ($Args::args{'inv10'} ne "") - && ($Args::args{'inv10'} =~ /^\s*($::REG_INVESTIG)\s*$/o)) - { - print INVES "$1\n"; - push @invs, $1; - } - - close(INVES); - - Print::log_session_info("Case $case created"); - - print "<br><br>We must now create a host for this case.\n"; - - print "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_ADD\">\n" - . "<input type=\"hidden\" name=\"case\" value=\"$case\">\n"; - - if (scalar @invs == 0) { - print "<option hiddden name=\"inv\" value=\"unknown\">\n"; - } - else { - print "<br><br>Please select your name from the list: " - . "<select name=\"inv\" size=\"1\">\n"; - - foreach $i (@invs) { - print "<option value=\"$i\">$i</option>\n"; - } - print "</select>\n"; - } - - print "<br><br>" - . "<input type=\"image\" src=\"pict/menu_b_hnew.jpg\" alt=\"Add New Host\" " - . "height=20 border=\"0\"></form>\n"; - - Print::print_html_footer(); - return; -} - -# Open a Case -# This provides a form with a list of options -sub case_open { - Print::print_html_header("Open A Case"); - - # Read the directories of the Evidence Locker into an array - # Verify that there is a config file in the directory - my @cases; - opendir CASES, $::LOCKDIR or die "Can't open $::LOCKDIR directory: $!"; - foreach my $c (readdir CASES) { - next if (($c eq '.') || ($c eq '..')); - my $cfile = Caseman::case_config_fname($c); - - push @cases, $c - if ((-d "$::LOCKDIR/$c") && (-e "$cfile")); - } - closedir CASES; - - print "<br><br><center>"; - - # Were there any cases? - if (scalar @cases == 0) { - print "No cases exist in <tt>$::LOCKDIR</tt><br><br>\n" - . "Select the New Case button below to make one<br>\n"; - } - else { - - print "Select the case to open or create a new one<br>\n"; - - print_menu_tabs(); - - print "<table width=\"600\" background=\"$::YEL_PIX\" " - . " cellspacing=\"0\" cellpadding=\"2\" border=0>\n"; - - print "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_OPEN_LOG\">\n" - . Args::make_hidden() - . "<tr><th>Name</th>" - . "<th>Description</th>" - . "<td> </td></tr>\n"; - - my $first = 0; - foreach my $c (@cases) { - - print "<tr><td align=\"left\">" - . "<input type=\"radio\" name=\"case\" value=$c"; - if ($first == 0) { - print " CHECKED"; - $first = 1; - } - print ">" . Print::html_encode($c) . "</td>"; - - Caseman::read_case_config($c); - - print "<td>$Caseman::cvals{'desc'}</td>" - . "<td align=center>" - . "<a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::CASE_DETAILS&case=$c\">" - . "details</a></td>" - . "</tr>\n"; - } - print "</table>\n"; - } - - print "<br><br>" - . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" - . "<tr>\n"; - - # Print the OK button if there were cases - if (scalar @cases != 0) { - print "<td align=center>" - . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" " - . "width=167 height=20 alt=\"Ok\" border=0>" - . "</form></td>\n\n"; - } - - # Print a 'New Case' Button - print "<td align=center>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_NEW\">\n" - . "<input type=\"image\" src=\"pict/menu_b_cnew.jpg\" " - . "width=167 height=20 alt=\"New Case\" border=0>\n" - . "</form></td>" - . - - # Print a Menu Button - "<td align=center>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"image\" src=\"pict/menu_b_menu.jpg\" " - . "width=167 height=20 alt=\"Main Menu\" border=0>\n" - . "</form></td></tr></table>\n"; - - print "<table width=600 cellspacing=\"0\" cellpadding=\"2\">\n<tr>" - . "<td> </td>\n" - . "<td align=center width=200><a href=\"$::HELP_URL\" " - . " target=\"_blank\">" - . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " - . "width=\"167\" height=20 border=0>" - . "</a></td>" - . "<td> </td>\n" - . "</tr>\n" - . "</table>"; - - Print::print_html_footer(); - return; -} - -# Log that a given case was opened and then proceed to open a host -sub case_open_log { - Print::log_session_info("Case $Args::args{'case'} opened"); - Print::log_case_info("Case $Args::args{'case'} opened"); - $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::HOST_OPEN; - host_open(); -} - -# Display Case Details -sub case_details { - - Print::print_html_header("Details of $Args::args{'case'}"); - - read_case_config(); - - print "<br><br>" - . "<center>" - . "<img src=\"pict/menu_h_cdet.jpg\" alt=\"Case Details\">" - . "<br><br><br>\n" - . "<table width=\"600\" cellspacing=\"0\" background=\"$::YEL_PIX\" " - . "cellpadding=\"2\" border=0>\n" - . " <tr><td align=\"right\" width=300><b>Name:</b></td>" - . "<td align=\"left\" width=300><tt>$Args::args{'case'}</tt></td></tr>\n" - . - - # Description - " <tr><td align=\"right\"><b>Description:</b></td>" - . "<td align=\"left\"><tt>$Caseman::cvals{'desc'}</tt></td></tr>\n" - . " <tr><td align=\"right\"><b>Created:</b></td>" - . "<td align=\"left\"><tt>$Caseman::cvals{'created'}</tt></td></tr>\n"; - - # Display the valid investigators - my @invs = read_invest(); - my $cnt = 0; - print " <tr><td colspan=\"2\"> </td></tr>\n" - if (scalar @invs > 0); - - foreach my $i (@invs) { - if ($cnt == 0) { - print " <tr><td align=\"right\"><b>Investigators:</b></td>"; - $cnt++; - } - else { - print " <tr><td> </td>"; - } - print "<td align=\"left\"><tt>" - . Print::html_encode($i) - . "</tt></td></tr>\n"; - } - - print "</table>\n" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::CASE_OPEN\">" - . "<img src=\"pict/menu_b_ok.jpg\" alt=\"Ok\" " - . "width=\"167\" height=20 border=\"0\"></a>"; - - Print::print_html_footer(); - return 0; -} - -#################################################################### -# Host Functions - -# if no args are passed, return host config using args{'host'}, -# else use the host value passed -sub host_config_fname { - if (scalar(@_) == 1) { - my $h = shift; - return "$::case_dir" . "$h/host.aut"; - } - else { - return "$::host_dir" . "host.aut"; - } -} - -# Converts the original single image host config to the volume-based config -sub convert_host_config { - - return if ($::LIVE == 1); - - my $host = Args::get_host(); - - Print::log_host_info("Converting host config files"); - print STDERR "Converting host config file to new format\n"; - - # The file to convert - my $cfile = host_config_fname(); - unless (open(FILE, $cfile)) { - Print::print_check_err("Error opening $cfile"); - } - - my $tmpcfile = "$::host_dir" . "host-convert.aut"; - unless (open(FILE_TMP, ">>$tmpcfile")) { - Print::print_check_err("Error opening $tmpcfile"); - } - - my $img_cnt = 0; - my $vol_cnt = 0; - $img2vol{'qazwsxedc'} = ""; # stores the image path to partition / file name - $img2vol2{'qazwsxedc'} = - ""; # stores the image path to file name (no partitions) - - while (<FILE>) { - if ((/^\#/) || (/^\s+$/)) { - print FILE_TMP $_; - next; - } - - # remove whitespace - s/^\s+//; - s/\s+$//; - - # normal file system image entry - # - # 'image images/hda1.dd openbsd /usr - if (/^image\s+($::REG_IMG)\s+([\w\-]+)\s+([\w\-\_\.\/:\\]+)$/o) { - - my $i = $1; - my $t = $2; - my $r = $3; - - # Add trailing / to original mount point if needed - if (($r !~ /.*?\/$/) && ($r !~ /.*?\\$/)) { - $r .= '/'; - } - my $vnum = "vol" . $vol_cnt; - my $inum = "img" . $img_cnt; - $img2vol{$i} = $vnum; - $img2vol2{$i} = $inum; - - print FILE_TMP "image $inum raw $i\n"; - print FILE_TMP "part $vnum $inum 0 0 $t $r\n"; - - $img_cnt++; - $vol_cnt++; - } - - # swap - # swap images/hda3.dd - elsif (/^swap\s+($::REG_IMG)\s*$/o) { - my $i = $1; - - my $vnum = "vol" . $vol_cnt; - my $inum = "img" . $img_cnt; - $img2vol{$i} = $vnum; - $img2vol2{$i} = $inum; - - print FILE_TMP "image $inum raw $i\n"; - print FILE_TMP "part $vnum $inum 0 0 swap\n"; - $img_cnt++; - $vol_cnt++; - - } - - # raw - # raw images/hda3.dd - elsif (/^raw\s+($::REG_IMG)\s*$/o) { - my $i = $1; - $img2vol{$i} = "vol" . $vol_cnt; - $img2vol2{$i} = "img" . $img_cnt; - - print FILE_TMP "image img" . $img_cnt . " raw $i\n"; - print FILE_TMP "part vol" . $vol_cnt . " img" . $img_cnt - . " 0 0 raw\n"; - $img_cnt++; - $vol_cnt++; - } - - # entry for a strings or blkls file - # - # strings data/hda1.str images/hda1.dd - elsif (/^strings\s+($::REG_IMG)\s+($::REG_IMG)$/o) { - my $i = $1; - my $o = $2; - - if (exists $img2vol{$o}) { - my $vname = $img2vol{$o}; - print FILE_TMP "strings vol" . $vol_cnt . " $vname $i\n"; - $img2vol{$i} = "vol" . $vol_cnt; - $img2vol2{$i} = "vol" . $vol_cnt; - } - else { - print STDERR "Error: Volume for strings $o not found<br>\n"; - } - $vol_cnt++; - } - - # entry for a strings or blkls file - # - # unistrings data/hda1.str images/hda1.dd - elsif (/^unistrings\s+($::REG_IMG)\s+($::REG_IMG)$/o) { - my $i = $1; - my $o = $2; - - if (exists $img2vol{$o}) { - my $vname = $img2vol{$o}; - print FILE_TMP "unistrings vol" . $vol_cnt - . " $vname $i\n"; - $img2vol{$i} = "vol" . $vol_cnt; - $img2vol2{$i} = "vol" . $vol_cnt; - } - else { - print STDERR - "Error: Volume for unicode strings $o not found<br>\n"; - } - $vol_cnt++; - } - - # blkls entry - # blkls data/image.blkls [images/image.dd] - elsif (/^blkls\s+($::REG_IMG)\s*($::REG_IMG)$/o) { - my $i = $1; - my $o = $2; - - $img2vol{$i} = "vol" . $vol_cnt; - - if (exists $img2vol{$o}) { - my $vname = $img2vol{$o}; - print FILE_TMP "blkls vol" . $vol_cnt . " $vname $i\n"; - $img2vol{$i} = "vol" . $vol_cnt; - $img2vol2{$i} = "vol" . $vol_cnt; - } - else { - print STDERR "Error: Volume for blkls $o not found<br>\n"; - } - $vol_cnt++; - } - - # body data/body.txt - elsif (/^body\s+($::REG_IMG)$/o) { - my $i = $1; - print FILE_TMP "body vol" . $vol_cnt . " $i\n"; - $img2vol{$i} = "vol" . $vol_cnt; - $img2vol2{$i} = "vol" . $vol_cnt; - - $vol_cnt++; - } - - # timeline data/timeline.txt - elsif (/^timeline\s+($::REG_IMG)$/o) { - my $i = $1; - print FILE_TMP "timeline vol" . $vol_cnt . " $i\n"; - $img2vol{$i} = "vol" . $vol_cnt; - $img2vol2{$i} = "vol" . $vol_cnt; - $vol_cnt++; - } - - # timezone XYZ - elsif (/^timezone\s+($::REG_ZONE_ARGS)$/o) { - print FILE_TMP "$_\n"; - } - - # timeskew XYZ - elsif (/^timeskew\s+($::REG_SKEW)$/o) { - print FILE_TMP "$_\n"; - } - - # desc XYZ - elsif (/^desc\s+(.*)$/) { - print FILE_TMP "$_\n"; - } - - # hash databases - elsif (/^alert_db\s+'(.*)'$/) { - print FILE_TMP "$_\n"; - } - elsif (/^exclude_db\s+'(.*)'$/) { - print FILE_TMP "$_\n"; - } - else { - my $msg = - "Error: invalid entry in $cfile:$." . "\n" - . "image path fs_type mnt_point\n" - . "strings path orig_img\n" - . "blkls path [orig_img]\n" - . "body path\n" - . "timeline path\n" - . "timezone TZ\n" - . "desc DESCRIPTION\n"; - Print::print_check_err($msg); - } - } - - close(FILE); - close(FILE_TMP); - unless (rename $cfile, $cfile . ".bak") { - print STDERR "Error backing up original host config file\n"; - } - unless (rename $tmpcfile, $cfile) { - print STDERR "Error renaming new host config file\n"; - } - - Notes::convert(\%img2vol); - Hash::convert(\%img2vol2); -} - -# reads host config file and sets global hash values for images and other -sub read_host_config { - - if ($::LIVE == 1) { - %Caseman::mod2vol = (); - %Caseman::vol2str = (); - %Caseman::vol2uni = (); - %Caseman::vol2blkls = (); - $Caseman::tz = ""; - $Caseman::ts = 0; - $Caseman::host_desc = ""; - $Caseman::exclude_db = ""; - $Caseman::alert_db = ""; - return; - } - - my $host = Args::get_host(); - - my $cfile = host_config_fname(); - restart: - unless (open(FILE, $cfile)) { - Print::print_check_err("Error opening $cfile"); - } - - %Caseman::vol2mnt = (); - %Caseman::vol2ftype = (); - %Caseman::vol2dtype = (); - %Caseman::vol2cat = (); - %Caseman::mod2vol = (); - %Caseman::vol2str = (); - %Caseman::vol2uni = (); - %Caseman::vol2blkls = (); - %Caseman::vol2par = (); - %Caseman::vol2start = (); - %Caseman::vol2end = (); - $Caseman::vol2path = (); - $Caseman::vol2sname = (); - - $Caseman::tz = ""; - $Caseman::ts = 0; - $Caseman::host_desc = ""; - $Caseman::exclude_db = ""; - $Caseman::alert_db = ""; - - while (<FILE>) { - next if ((/^\#/) || (/^\s+$/)); - - # remove whitespace - s/^\s+//; - s/\s+$//; - - # old file system image entry - # - # 'image images/hda1.dd openbsd /usr - if (/^image\s+($::REG_IMG)\s+([\w\-]+)\s+([\w\-\_\.\/:\\]+)$/o) { - - close(FILE); - convert_host_config(); - goto restart; - } - elsif ( - /^image\s+($::REG_INAME)\s+($::REG_IMGTYPE)\s+($::REG_IMG_CONFIG)$/o - ) - { - my $me = $1; - my $t = $2; - my $i = $3; - - unless ((-e "$::host_dir$i") - || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) - { - Print::print_check_err( - "Error: image $i in ${host}.host:$. not found: " - . "$::host_dir" - . "$i \nEdit the config file and refresh your browser\n" - . "(Or your version of Perl does not support large files)" - ); - } - - if (exists $Caseman::vol2path{$me}) { - $Caseman::vol2path{$me} .= " \'$::host_dir" . "$i\'"; - } - else { - $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; - $Caseman::vol2sname{$me} = $i; - $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); - - $Caseman::vol2par{$me} = ""; - $Caseman::vol2cat{$me} = "image"; - $Caseman::vol2itype{$me} = $t; - $Caseman::vol2ftype{$me} = ""; - - $Caseman::vol2start{$me} = 0; - $Caseman::vol2end{$me} = 0; - } - } - elsif ( -/^part\s+($::REG_VNAME)\s+($::REG_INAME)\s+(\d+)\s+(\d+)\s+($::REG_FTYPE)\s*([\w\-\_\.\/:\\]+)?$/o - ) - { - my $par = $2; - my $me = $1; - my $s = $3; - my $e = $4; - my $t = $5; - my $r = $6; # Not defined for swap and raw - - unless (exists $Fs::addr_unit{$t}) { - Print::print_check_err( - "Error: unknown type: $t in host config: $." - . "\nEdit the file and refresh your browser"); - } - - if (exists $Caseman::vol2itype{$par}) { - $Caseman::vol2itype{$me} = $Caseman::vol2itype{$par}; - } - else { - Print::print_check_err( -"Error: Image $par for partition $me was not found in config: $." - . "\nEdit the file and refresh your browser"); - } - - $Caseman::vol2ftype{$me} = $t; - $Caseman::vol2cat{$me} = "part"; - $Caseman::vol2start{$me} = $s; - $Caseman::vol2end{$me} = $e; - - # Add trailing / to original mount point if needed - if ((defined $r) && ($r !~ /.*?\/$/) && ($r !~ /.*?\\$/)) { - $r .= '/'; - } - $Caseman::vol2mnt{$me} = $r; - $Caseman::vol2par{$me} = $par; - $Caseman::vol2path{$me} = $Caseman::vol2path{$par}; - $Caseman::vol2sname{$me} = - $Caseman::vol2sname{$par} . "-" . $s . "-" . $e; - } - elsif (/^disk\s+($::REG_VNAME)\s+($::REG_INAME)\s+($::REG_FTYPE)?$/o) { - my $par = $2; - my $me = $1; - my $t = $3; - - unless (exists $Vs::type{$t}) { - Print::print_check_err( - "Error: unknown volume system type: $t in host config: $." - . "\nEdit the file and refresh your browser"); - } - - if (exists $Caseman::vol2itype{$par}) { - $Caseman::vol2itype{$me} = $Caseman::vol2itype{$par}; - } - else { - Print::print_check_err( -"Error: Image $par for disk $me was not found in config: $.\n" - . "Edit the file and refresh your browser"); - } - - $Caseman::vol2ftype{$me} = "raw"; - $Caseman::vol2dtype{$me} = $t; - $Caseman::vol2cat{$me} = "disk"; - $Caseman::vol2start{$me} = 0; - $Caseman::vol2end{$me} = 0; - $Caseman::vol2mnt{$me} = ""; - $Caseman::vol2par{$me} = $par; - $Caseman::vol2path{$me} = $Caseman::vol2path{$par}; - $Caseman::vol2sname{$me} = $Caseman::vol2sname{$par} . "-disk"; - } - - # entry for a strings or blkls file - # - # strings data/hda1.str volX - elsif (/^strings\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o) { - my $i = $3; - my $par = $2; - my $me = $1; - - unless ((-e "$::host_dir$i") - || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) - { - Print::print_check_err("Error: strings file not found: " - . "$::host_dir$i\nEdit host config in $::host_dir and refresh your browser" - ); - } - - unless (exists $Caseman::vol2cat{$par}) { - Print::print_check_err( -"Error: Volume $par for strings $me was not found in config: $." - . "\nEdit the file and refresh your browser"); - } - - $Caseman::vol2ftype{$me} = "strings"; - $Caseman::vol2cat{$me} = "mod"; - $Caseman::vol2itype{$me} = "raw"; - $Caseman::mod2vol{$me} = $par; - $Caseman::vol2str{$par} = $me; - $Caseman::vol2par{$me} = $par; - $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; - $Caseman::vol2start{$me} = 0; - $Caseman::vol2end{$me} = 0; - $Caseman::vol2sname{$me} = $i; - $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); - - } - - # entry for a strings or blkls file - # - # unistrings data/hda1.str volX - elsif (/^unistrings\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o) - { - my $i = $3; - my $par = $2; - my $me = $1; - - unless ((-e "$::host_dir$i") - || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) - { - Print::print_check_err("Error: Unicode strings file not found: " - . "$::host_dir$i\nEdit host config in $::host_dir and refresh your browser" - ); - } - - unless (exists $Caseman::vol2cat{$par}) { - Print::print_check_err( -"Error: Volume $par for unistrings $me was not found in config: $." - . "\nEdit the file and refresh your browser"); - } - - $Caseman::vol2ftype{$me} = "strings"; - $Caseman::vol2cat{$me} = "mod"; - $Caseman::vol2itype{$me} = "raw"; - $Caseman::mod2vol{$me} = $par; - $Caseman::vol2uni{$par} = $me; - $Caseman::vol2par{$me} = $par; - $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; - $Caseman::vol2start{$me} = 0; - $Caseman::vol2end{$me} = 0; - $Caseman::vol2sname{$me} = $i; - $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); - } - - # blkls entry - # blkls themname myname - elsif ((/^blkls\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o) || - (/^dls\s+($::REG_VNAME)\s+($::REG_VNAME)\s+($::REG_IMG)$/o)) { - my $i = $3; - my $par = $2; - my $me = $1; - - unless ( - (-e "$::host_dir$i") - || ( (-l "$::host_dir$i") - && (-e readlink "$::host_dir$i")) - ) - { - Print::print_check_err("Error: blkls file not found: " - . "$::host_dir$i \nEdit host config in $::host_dir and refresh your browser" - ); - } - - unless (exists $Caseman::vol2cat{$par}) { - Print::print_check_err( -"Error: Volume $par for blkls $me was not found in config: $." - . "\nEdit the file and refresh your browser"); - } - - $Caseman::vol2ftype{$me} = "blkls"; - $Caseman::vol2cat{$me} = "mod"; - $Caseman::vol2itype{$me} = "raw"; - $Caseman::vol2mnt{$me} = ""; - $Caseman::vol2par{$me} = $par; - $Caseman::mod2vol{$me} = $par; - $Caseman::vol2blkls{$par} = $me; - $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; - $Caseman::vol2start{$me} = 0; - $Caseman::vol2end{$me} = 0; - $Caseman::vol2sname{$me} = $i; - $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); - - } - - # body data/body.txt - elsif (/^body\s+($::REG_VNAME)\s+($::REG_IMG)$/o) { - my $me = $1; - my $i = $2; - - unless ((-e "$::host_dir$i") - || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) - { - Print::print_check_err("Error: body file not found: " - . "$::host_dir$i <br>Edit host config in $::host_dir and refresh your browser" - ); - } - - $Caseman::vol2cat{$me} = "timeline"; - $Caseman::vol2ftype{$me} = "body"; - $Caseman::vol2itype{$me} = "raw"; - $Caseman::vol2path{$me} = "\'$::host_dir" . "$i\'"; - $Caseman::vol2start{$me} = 0; - $Caseman::vol2end{$me} = 0; - $Caseman::vol2sname{$me} = $i; - $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); - } - - # timeline data/timeline.txt - elsif (/^timeline\s+($::REG_VNAME)\s+($::REG_IMG)$/o) { - my $me = $1; - my $i = $2; - - unless ((-e "$::host_dir$i") - || ((-l "$::host_dir$i") && (-e readlink "$::host_dir$i"))) - { - Print::print_check_err("Error: timeline file not found: " - . "$::host_dir$i \nEdit host config in $::host_dir and refresh your browser" - ); - } - - $Caseman::vol2cat{$me} = "timeline"; - $Caseman::vol2ftype{$me} = "timeline"; - $Caseman::vol2itype{$me} = "raw"; - -# We do not add the quotes to the path for timeline because it is opened only by the Perl code and it doesn't like the quotes - $Caseman::vol2path{$me} = "$::host_dir" . "$i"; - $Caseman::vol2start{$me} = 0; - $Caseman::vol2end{$me} = 0; - $Caseman::vol2sname{$me} = $i; - $Caseman::vol2sname{$me} = $1 if ($i =~ /\/($::REG_FILE)$/); - - } - - # timezone XYZ - elsif (/^timezone\s+($::REG_ZONE_ARGS)$/o) { - $Caseman::tz = "\'$1\'"; - } - - # timeskew XYZ - elsif (/^timeskew\s+($::REG_SKEW)$/o) { - $Caseman::ts = "\'$1\'"; - } - - # desc XYZ - elsif (/^desc\s+(.*)$/) { - $Caseman::host_desc = Print::html_encode($1); - } - - # hash databases - elsif (/^alert_db\s+'($::REG_HASHDB)'$/) { - $Caseman::alert_db = "$1"; - } - elsif (/^exclude_db\s+'($::REG_HASHDB)'$/) { - $Caseman::exclude_db = "$1"; - } - else { - my $msg = "Error: invalid entry in $cfile:$." . "\n" . "$_\n"; - Print::print_check_err($msg); - } - } - close(FILE); -} - -# Add a new image entry to the host config and return its id -sub add_img_host_config { - my $type = shift; - my $other = shift; - my $id = shift; - - my $read = host_config_fname(); - my $write = $read . "-" . rand(); - - unless (open(READ, "<$read")) { - Print::print_check_err("Error opening $read"); - } - - unless (open(WRITE, ">$write")) { - Print::print_check_err("Error opening $write"); - } - - my $maxcnt = 0; - - while (<READ>) { - s/^\s+//; - s/\s+$//; - if (/^\w+\s+img(\d+)\s+.*$/) { - $maxcnt = $1 if ($1 > $maxcnt); - } - print WRITE "$_\n"; - } - $maxcnt++; - if ($id eq "") { - $id = "img" . $maxcnt; - } - print WRITE "$type $id $other\n"; - - Print::log_host_info("Image added: $type $id $other"); - - close(READ); - close(WRITE); - unless (rename $write, $read) { - print STDERR "Error renaming temp host config file\n"; - } - - return $id; -} - -# Add a new volume entry to the host config and return its id -sub add_vol_host_config { - my $type = shift; - my $other = shift; - - my $read = host_config_fname(); - my $write = $read . "-" . rand(); - - unless (open(READ, "<$read")) { - Print::print_check_err("Error opening $read"); - } - - unless (open(WRITE, ">$write")) { - Print::print_check_err("Error opening $write"); - } - - # We want to find the max count ... not just the unused - # ones because we could end up reusing one and that could - # mess up the notes - my $maxcnt = 0; - - while (<READ>) { - s/^\s+//; - s/\s+$//; - if (/^\w+\s+vol(\d+)\s+.*$/) { - $maxcnt = $1 if ($1 > $maxcnt); - } - print WRITE "$_\n"; - } - $maxcnt++; - print WRITE "$type vol" . $maxcnt . " $other\n"; - Print::log_host_info("Volume added: $type vol" . $maxcnt . " $other"); - - close(READ); - close(WRITE); - unless (rename $write, $read) { - print STDERR "Error renaming temp host config file\n"; - } - - return "vol" . $maxcnt; -} - -# Delete anentry from the host config -# DOES NOT WORK RIGHT NOW -sub del_host_config_BLAH { - return; - my $type = shift; - my $other = shift; - - my $read = host_config_fname(); - my $write = $read . "-" . rand(); - - unless (open(READ, "<$read")) { - Print::print_check_err("Error opening $read"); - } - - unless (open(WRITE, ">$write")) { - Print::print_check_err("Error opening $write"); - } - - while (<READ>) { - s/^\s+//; - s/\s+$//; - print WRITE "$_\n" - unless ((/^(\w+)\s+($::REG_IMG)/o) - && ($2 eq $img) - && ($1 ne 'desc') - && ($1 ne 'timezone')); - } - - if ($type ne "") { - if (defined $ref) { - print WRITE "$type $img $ref\n"; - } - else { - print WRITE "$type $img\n"; - } - } - - close(READ); - close(WRITE); - unless (rename $write, $read) { - print STDERR "Error renaming temp host config file\n"; - } - - return; -} - -# Given the image and md5, it is saved to the MD5.txt file and any other -# references to the image are removed -# -# if $md5 is "", then nothing is written -sub update_md5 { - my $vol = shift; - my $md5 = shift; - $md5 =~ tr/[a-f]/[A-F]/; - - my $read = "$::host_dir/md5.txt"; - my $write = $read . "-" . rand(); - - unless (open(WRITE, ">$write")) { - Print::print_check_err("Error opening $write"); - } - - if (-e "$read") { - unless (open(READ, "<$read")) { - Print::print_check_err("Error opening $read"); - } - - while (<READ>) { - s/^\s+//; - s/\s+$//; - print WRITE "$_\n" - unless ((/^$::REG_MD5\s+($::REG_VNAME)/o) && ($1 eq $vol)); - } - close(READ); - } - - print WRITE "$md5 $vol\n" if ($md5 ne ""); - - close(WRITE); - - unless (rename $write, $read) { - print STDERR "Error renaming temp MD5 hash file\n"; - } - return; -} - -sub host_add { - Print::print_html_header("Add A New Host To $Args::args{'case'}"); - - print "<b>Case: </b> $Args::args{'case'}<br><br>\n"; - - print "<center>" - . "<img src=\"pict/menu_h_hnew.jpg\" alt=\"Add Host\">" - . "<br><br><br>\n"; - - print "<table width=\"600\" cellspacing=\"0\" background=\"$::YEL_PIX\" " - . "cellpadding=\"2\" border=0>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_ADD_DOIT\">\n" - . Args::make_hidden() - . "<tr><td colspan=\"2\"> </td></tr>" - . - - # Host name -"<tr><td align=\"left\" colspan=2>1. <b>Host Name:</b> The name of the computer being investigated. It can contain only letters, numbers, and symbols.</td></tr>" - . "<tr><td align=\"left\">   </td>" - . "<td align=\"left\"><input type=\"text\" name=\"host\" size=32 maxlength=32 value=\"host1\"></td></tr>\n" - . - - # Description -"<tr><td align=\"left\" colspan=2>2. <b>Description:</b> An optional one-line description or note about this computer.</td></tr>" - . "<tr><td align=\"left\">   </td>" - . "<td align=\"left\">" - . "<input type=\"text\" name=\"desc\" size=32 maxlength=32></td></tr>\n" - . - - # Empty line - "<tr><td colspan=\"2\"> </td></tr>" . - - # Timezone -"<tr><td align=\"left\" colspan=2>3. <b>Time zone:</b> An optional timezone value (i.e. EST5EDT). If not given, it defaults to the local setting. A list of time zones can be found in the help files.</td></tr>" - . "<tr><td align=\"left\">   </td>" - . "<td align=\"left\">" - . "<input type=\"text\" name=\"tz\" size=16 maxlength=64></td></tr>\n" - . - - # Timeskew -"<tr><td align=\"left\" colspan=2>4. <b>Timeskew Adjustment:</b> An optional value to describe how many seconds this computer's clock was out of sync. For example, if the computer was 10 seconds fast, then enter -10 to compensate.</td></tr>" - . "<tr><td align=\"left\">   </td>" - . "<td align=\"left\">" - . "<input type=\"text\" name=\"ts\" size=8 maxlength=16 value=\"0\">" - . "</td></tr>\n" - . - - # Spacer - "<tr><td colspan=\"2\"> </td></tr>" . - - # Alert -"<tr><td align=\"left\" colspan=2>5. <b>Path of Alert Hash Database:</b> An optional hash database of known bad files.</td></tr>" - . "<tr><td align=\"left\">   </td>" - . "<td align=\"left\">" - . "<input type=\"text\" name=\"alert_db\" size=32 maxlength=512>" - . "</td></tr>\n" - . - - # Ignore -"<tr><td align=\"left\" colspan=2>6. <b>Path of Ignore Hash Database:</b> An optional hash database of known good files.</td></tr>" - . "<tr><td align=\"left\">   </td>" - . "<td align=\"left\">" - . "<input type=\"text\" name=\"exclude_db\" size=32 maxlength=512>" - . "</td></tr>\n" - . - - # Spacer - "<tr><td colspan=\"2\"> </td></tr>" . "</table>\n"; - - if (exists $Args::args{'inv'}) { - print - "<input type=\"hidden\" name=\"inv\" value=\"$Args::args{'inv'}\">\n"; - } - - # Ok Button - print "<br><br><table width=\"600\" cellspacing=\"8\" cellpadding=\"2\">\n" - . "<tr><td align=center>" - . "<input type=\"image\" src=\"pict/menu_b_hnew.jpg\" " - . "width=167 height=20 alt=\"Add Host\" border=0>\n" - . "</form></td>\n" - . - - # Cancel Button - "<td align=center>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN\">\n" - . "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" - . "<input type=\"image\" src=\"pict/menu_b_cancel.jpg\" " - . "alt=\"Cancel\" width=\"167\" height=20 border=0>\n" - . "</form></td>\n" - . - - # Help Button - "<td align=center><a href=\"$::HELP_URL\" " - . "target=\"_blank\">" - . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " - . "width=\"167\" height=20 border=0></a>" - . "</td></tr>\n" - . "</table>"; - - Print::print_html_footer(); - - return 0; -} - -# Make the directories and config files for a host -sub host_add_doit { - Args::check_tz() - if ((exists $Args::args{'tz'}) && ($Args::args{'tz'} ne "")); - Args::check_ts(); - Print::print_html_header( - "Adding Host $Args::args{'host'} to $Args::args{'case'}"); - - print "<h3>Adding host: <tt>$Args::args{'host'}</tt> to " - . "case <tt>$Args::args{'case'}</tt></h3>\n"; - - # Do some sanity checks before we start making the directories and such - if ( (exists $Args::args{'alert_db'}) - && ($Args::args{'alert_db'} ne "")) - { - - unless ($Args::args{'alert_db'} =~ /^$::REG_HASHDB$/o) { - print "Invalid Alert Database path\n" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" - . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=\"43\" height=20 border=\"0\"></a>\n"; - return 1; - } - - unless (-e "$Args::args{'alert_db'}") { - print "Alert Database Not Found: $Args::args{'alert_db'}" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" - . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=\"43\" height=20 border=\"0\"></a>\n"; - return 1; - } - } - - if ( (exists $Args::args{'exclude_db'}) - && ($Args::args{'exclude_db'} ne "")) - { - unless ($Args::args{'exclude_db'} =~ /^$::REG_HASHDB$/o) { - print "Invalid Exclude Database path\n" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" - . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=\"43\" height=20 border=\"0\"></a>\n"; - return 1; - } - - unless (-e "$Args::args{'exclude_db'}") { - print "Exclude Database Not Found: $Args::args{'exclude_db'}" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::HOST_ADD&case=$Args::args{'case'}\">" - . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=\"43\" height=20 border=\"0\"></a>\n"; - return 1; - } - } - - # Make the directory - if (-d "$::host_dir") { - - print "Error: $::host_dir already exists<br>" - . "Please remove the directory and its contents and try again" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::HOST_OPEN&case=$Args::enc_args{'case'}\">" - . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=\"43\" height=20 border=\"0\"></a>\n"; - Print::print_err("\n"); - } - unless (mkdir "$::host_dir", $::MKDIR_MASK) { - Print::print_err("Error making directory $::host_dir: $!"); - } - - print "Host Directory (<tt>$::host_dir</tt>) created<p>\n"; - Print::log_case_info("Host $Args::args{'host'} added to case"); - - # Images directory - unless (mkdir "$::host_dir" . "$::IMGDIR", $::MKDIR_MASK) { - rmdir "$::host_dir"; - Print::print_err("Error making $::host_dir" . "$::IMGDIR"); - } - - # Output Directory - unless (mkdir "$::host_dir" . "$::DATADIR", $::MKDIR_MASK) { - rmdir "$::host_dir" . "$::IMGDIR"; - rmdir "$::host_dir"; - Print::print_err("Error making $::host_dir" . "$::DATADIR"); - } - - # Log Directory - unless (mkdir "$::host_dir" . "$::LOGDIR", $::MKDIR_MASK) { - rmdir "$::host_dir" . "$::DATADIR"; - rmdir "$::host_dir" . "$::IMGDIR"; - rmdir "$::host_dir"; - Print::print_err("Error making $::host_dir" . "$::LOGDIR"); - } - - # Reports directory - unless (mkdir "$::host_dir" . "$::REPDIR", $::MKDIR_MASK) { - rmdir "$::host_dir" . "$::LOGDIR"; - rmdir "$::host_dir" . "$::DATADIR"; - rmdir "$::host_dir" . "$::IMGDIR"; - rmdir "$::host_dir"; - Print::print_err("Error making $::host_dir" . "$::REPDIR"); - } - - # Make a directory for mounting the image in loopback - unless (mkdir "$::host_dir" . "mnt", $::MKDIR_MASK) { - rmdir "$::host_dir" . "$::REPDIR"; - rmdir "$::host_dir" . "$::LOGDIR"; - rmdir "$::host_dir" . "$::DATADIR"; - rmdir "$::host_dir" . "$::IMGDIR"; - rmdir "$::host_dir"; - Print::print_err("Error making $::host_dir" . "mnt"); - } - - Print::log_host_info( - "Host $Args::args{'host'} added to case $Args::args{'case'}"); - - # Create config file - my $fname = Caseman::host_config_fname(); - open HOST_CONFIG, ">$fname" or die "Can't open host config: $fname"; - - print HOST_CONFIG "# Autopsy host config file\n" - . "# Case: $Args::args{'case'} Host: $Args::args{'host'}\n" - . "# Created: " - . localtime() . "\n\n"; - - if ((exists $Args::args{'desc'}) && ($Args::args{'desc'} ne "")) { - Print::print_err( - "Invalid Description\n" . "Use the browser's back button to fix") - if ($Args::args{'desc'} =~ /\n/); - - print HOST_CONFIG "desc $Args::args{'desc'}\n"; - } - - print HOST_CONFIG "timezone " . Args::get_tz() . "\n" - if ((exists $Args::args{'tz'}) && ($Args::args{'tz'} ne "")); - print HOST_CONFIG "timeskew " . Args::get_ts() . "\n"; - - if ( (exists $Args::args{'alert_db'}) - && ($Args::args{'alert_db'} ne "")) - { - - # Index it if it is not - unless (-e "$Args::args{'alert_db'}-md5.idx") { - print -"Alert Database has not been indexed - it will be as an md5sum file<br>\n"; - - print "<hr>\n"; - Hash::index_md5sum($Args::args{'alert_db'}); - print "<hr>\n"; - } - - # only print it if it was successful - print HOST_CONFIG "alert_db \'$Args::args{'alert_db'}\'\n" - if (-e "$Args::args{'alert_db'}-md5.idx"); - } - - if ( (exists $Args::args{'exclude_db'}) - && ($Args::args{'exclude_db'} ne "")) - { - - # Index it if it is not - unless (-e "$Args::args{'exclude_db'}-md5.idx") { - print -"Exclude Database has not been indexed - it will be as an md5sum file<br>\n"; - - print "<hr>\n"; - Hash::index_md5sum($Args::args{'exclude_db'}); - print "<hr>\n"; - } - - # only print it if it was successful - print HOST_CONFIG "exclude_db \'$Args::args{'exclude_db'}\'\n" - if (-e "$Args::args{'exclude_db'}-md5.idx"); - } - - close HOST_CONFIG; - - print "Configuration file (<tt>$fname</tt>) created<br><br>\n"; - - print "We must now import an image file for this host\n"; - - print "<br><br><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::HOST_OPEN_LOG&$Args::baseargs\">" - . "<img src=\"pict/menu_b_inew.jpg\" alt=\"Add Image\" " - . " height=20 border=\"0\"></a>\n"; - - Print::print_html_footer(); - return 0; -} - -# Open a host in the given case -sub host_open { - Print::print_html_header("Open Host In $Args::args{'case'}"); - - # Create an array of directories in the case, verifying that there is - # a config file - my @hosts; - opendir HOSTS, $::case_dir or die "Can't open $::case_dir directory: $!"; - foreach my $h (readdir HOSTS) { - next if (($h eq '.') || ($h eq '..')); - - my $hfile = Caseman::host_config_fname($h); - push @hosts, $h - if ((-d "$::case_dir" . "$h") && (-e "$hfile")); - } - closedir HOSTS; - - print "<b>Case:</b> $Args::args{'case'}<br><br>\n"; - - print "<center>"; - - if (scalar @hosts == 0) { - print "No hosts have been added to the case yet" - . "<br><br>Select the Add Host button below to create one.<br>\n"; - } - else { - - print "Select the host to open or create a new one<br>\n"; - - print_menu_tabs(); - - print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " - . "background=\"$::YEL_PIX\" border=0>\n"; - - print "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN_LOG\">\n" - . Args::make_hidden() - . "<tr><th>Name</th>" - . "<th>Description</th><th> </th></tr>\n"; - - my $first = 0; - foreach my $h (@hosts) { - - print "<tr><td align=\"left\">" - . "<input type=\"radio\" name=\"host\" value=$h"; - if ($first == 0) { - print " CHECKED"; - $first = 1; - } - print "> " . Print::html_encode($h) . " </td>"; - - my $fname = Caseman::host_config_fname($h); - open CONFIG, "<$fname" - or die "Can't open host config file ($fname)"; - - my $desc = "None Provided"; - while (<CONFIG>) { - s/^\s+//; - s/\s+$//; - - if (/^desc\s+(.*)$/) { - $desc = Print::html_encode($1); - last; - } - } - close CONFIG; - - print "<td align=left>$desc</td>" - . "<td align=center>" - . "<a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::HOST_DETAILS&$Args::baseargs&" - . "host=$h\">details</a></td></tr>\n"; - } - print "</table>\n"; - - # Display pulldown of investigators - my @invs = read_invest(); - if (scalar @invs == 0) { - print "<input type=\"hidden\" name=\"inv\" value=\"unknown\">\n"; - } - else { - print "<br>Investigator (for reports only): "; - my $cur_inv = ""; - $cur_inv = $Args::args{'inv'} if (exists $Args::args{'inv'}); - - print "<select name=\"inv\" size=\"1\">\n"; - - if (($cur_inv eq "") && (scalar @invs != 1)) { - print "<option value=\"\" selected>Select One" . "</option>\n"; - } - foreach my $i (@invs) { - print "<option value=\"$i\""; - print " selected" if ($cur_inv eq $i); - print ">" . Print::html_encode($i) . "</option>\n"; - } - print "</select>\n"; - } - } - print "<br><br><table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" - . "<tr>\n"; - - # Make a table for the buttons. The table will either be 3 or 2 - # entries wide, depending on if there is an 'Ok' button or not - - unless (scalar @hosts == 0) { - print "<td align=center>" - . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" " - . "alt=\"Ok\" width=\"167\" height=20 border=0>\n" - . "</form>\n</td>\n"; - } - - # Add Host - print "<td align=center>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_ADD\">\n" - . "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" - . "<input type=\"image\" src=\"pict/menu_b_hnew.jpg\" " - . "alt=\"Add Host\" width=\"176\" height=20 border=0>\n" - . "</form></td>" - . - - # Close Button - "<td align=center>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::CASE_OPEN\">\n" - . "<input type=\"image\" src=\"pict/menu_b_ccls.jpg\" " - . "alt=\"Close Case\" width=\"176\" height=20 border=0>\n" - . "</form></td></tr></table>\n"; - - print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" - . "<tr><td> </td>" - . "<td align=center><a href=\"$::HELP_URL\" " - . " target=\"_blank\">" - . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " - . "width=\"167\" height=20 border=0>" - . "</a></td><td> </td></tr>\n" - . "</table>\n"; - - Print::print_html_footer(); - return 0; -} - -# Log that a given host was opened and then proceed to open an image -sub host_open_log { - unless ((exists $Args::args{'inv'}) && ($Args::args{'inv'} ne "")) { - my @invs = read_invest(); - if (scalar @invs == 0) { - $Args::args{'inv'} = $Args::enc_args{'inv'} = 'unknown'; - } - else { - Print::print_html_header("Missing Investigator"); - print "<br>An investigator must be selected<p>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN_LOG\">\n" - . Args::make_hidden(); - - print "Select one of the following:"; - print "<select name=\"inv\" size=\"1\">\n"; - - print "<option value=\"\" selected>Select One" . "</option>\n"; - - foreach my $i (@invs) { - print "<option value=\"$i\">$i</option>\n"; - } - print "</select><p>\n" - . "<input type=\"image\" src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=43 height=20 border=\"0\">\n" - . "</form>\n"; - - Print::print_html_footer(); - return 0; - } - } - - Args::check_inv(); - Print::log_case_info( - "Host $Args::args{'host'} opened by $Args::args{'inv'}"); - Print::log_host_info( - "Host $Args::args{'host'} opened by $Args::args{'inv'}"); - Print::log_host_inv("Host $Args::args{'host'} opened"); - - $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::VOL_OPEN; - vol_open(); -} - -# Provide details about the configuration of a host. This window is -# a link from the HOST_OPEN window -sub host_details { - Print::print_html_header( - "Details of $Args::args{'case'}:$Args::args{'host'}"); - - print "<b>Case: </b>$Args::args{'case'}<br><br>" - . "<center>" - . "<img src=\"pict/menu_h_hdet.jpg\" alt=\"Host Details\">" - . "<br><br><br>\n" - . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " - . "background=\"$::YEL_PIX\" border=0>\n" - . - - # Name - "<tr><td align=\"right\" width=300><b>Name:</b></td>" - . "<td align=\"left\" width=300><tt>$Args::args{'host'}</tt></td></tr>\n" - . - - # Description - "<tr><td align=\"right\"><b>Description:</b></td>" - . "<td align=\"left\"><tt>" - . (($Caseman::host_desc ne "") ? $Caseman::host_desc : " ") - . "</tt></td></tr>\n" - . - - # Timezone - "<tr><td align=\"right\"><b>Time zone: </b></td>" - . "<td align=\"left\"><tt>$Caseman::tz</tt></td></tr>\n" - . - - # Timeskew - "<tr><td align=\"right\"><b>Timeskew:</b></td>" - . "<td align=\"left\"><tt>$Caseman::ts</tt></td></tr>\n" - . "<tr><td colspan=2> </td></tr>\n" - . - - # Actual Directory - "<tr><td align=\"right\"><b>Directory:</b></td>" - . "<td align=\"left\"><tt>" - . Print::html_encode($::host_dir) - . "</tt></td></tr>\n" - . "<tr><td colspan=2> </td></tr>\n" - . - - # Alert Database - "<tr><td align=\"right\"><b>Alert Hash Database:</b></td>" - . "<td align=\"left\"><tt>" - . (($Caseman::alert_db ne "") - ? Print::html_encode($Caseman::alert_db) - : " ") - . "</tt></td></tr>\n" - . - - # Exclude Database - "<tr><td align=\"right\"><b>Exclude Hash Database:</b></td>" - . "<td align=\"left\"><tt>" - . (($Caseman::exclude_db ne "") - ? Print::html_encode($Caseman::exclude_db) - : " ") - . "</tt></td></tr>\n" - . "</table>\n"; - - # Final Button - print "<br><br><form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" " - . "alt=\"Ok\" width=\"167\" height=20 border=\"0\">\n</form>"; - - Print::print_html_footer(); - - return; -} - -# Read the investigators file and return a sorted list -sub read_invest { - my $fname = investig_fname(); - open INVES, "<$fname" or return; - - my @investigs; - while (<INVES>) { - chomp; - s/^\s+//; - s/\s+$//; - push @investigs, $1 - if (/^($::REG_INVESTIG)$/o); - } - close(INVES); - sort { lc($a) cmp lc($b) } @investigs; -} - -# File of investigators name in list -sub investig_fname { - return "$::case_dir" . "investigators.txt"; -} - -#################################################################### -# Image Functions - -# Types of modes for fname (i.e. can we overwrite it if it exists) -my $FNAME_MODE_INIT = 0; -my $FNAME_MODE_OVER = 1; - -my $MD5_NOTHING = 1; -my $MD5_CALC = 2; -my $MD5_ADD = 3; - -my $IMG_ADD_SYM = 1; -my $IMG_ADD_COPY = 2; -my $IMG_ADD_MOVE = 3; - -# Open an image that has been configured -sub vol_open { - Print::print_html_header( - "Open Image In $Args::args{'case'}:$Args::args{'host'}"); - - print "<b>Case:</b> $Args::args{'case'}<br>\n"; - print "<b>Host:</b> $Args::args{'host'}<br>\n"; - print "<center>\n"; - - # the images have been loaded from reading the host config file in - # autopsy_main - if (scalar(keys %Caseman::vol2ftype) == 0) { - print "No images have been added to this host yet<br><br>\n" - . "Select the Add Image File button below to add one\n"; - goto EGRESS; - } - - if ($::LIVE == 1) { - print "Select a volume to analyze.<br>\n"; - } - else { - print "Select a volume to analyze or add a new image file.<br>\n"; - } - - print_menu_tabs(); - - print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " - . "background=\"$::YEL_PIX\" border=0>\n"; - - # We want to sort, so rearrange the hash - my %mnt2vol; - my %par2disk; - - # Cycle through each image we read from the host config - foreach my $i (keys %Caseman::vol2cat) { - if ($Caseman::vol2cat{$i} eq "disk") { - $mnt2vol{"1disk--AUTOPSY--$i"} = $i; - } - elsif ($Caseman::vol2cat{$i} eq "part") { - if ( ($Caseman::vol2ftype{$i} eq "raw") - || ($Caseman::vol2ftype{$i} eq "swap")) - { - $mnt2vol{"2$Caseman::vol2ftype{$i}--AUTOPSY--$i"} = $i; - } - else { - $mnt2vol{"2$Caseman::vol2mnt{$i}--AUTOPSY--$i"} = $i; - } - } - } - - # sort via parent volume, then starting location, - # and then mount point (which includes the name) - my @mnt = sort { - ($Caseman::vol2par{$mnt2vol{$a}} cmp $Caseman::vol2par{$mnt2vol{$b}}) - or ($Caseman::vol2start{$mnt2vol{$a}} <=> - $Caseman::vol2start{$mnt2vol{$b}}) - or (lc($a) cmp lc($b)) - } keys %mnt2vol; - - # It is possible to have only the blkls image and not the original - # We need to search for those now because they will not be in the - # list that we just made (which are arranged via mount point) - my @orphan_blkls; - - # cycle through each image and check its type and original - foreach my $k (keys %Caseman::vol2ftype) { - if ( ($Caseman::vol2ftype{$k} eq "blkls") - && (!exists $Caseman::mod2vol{$k})) - { - push @orphan_blkls, $k; - } - } - - print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN_LOG\">\n" - . Args::make_hidden() - - . "<tr><th> </th>" - . "<th align=left>mount</th>" - . "<th align=left>name</th>" - . # vol name - "<th align=left>fs type</th></tr>\n"; - - my $prev_par = ""; - - for (my $i = 0; $i <= $#mnt; $i++) { - my $vol = $mnt2vol{$mnt[$i]}; - - if ($Caseman::vol2par{$vol} ne $prev_par) { - print "<tr><td colspan=5><hr></td></tr>\n" if ($i != 0); - $prev_par = $Caseman::vol2par{$vol}; - } - - # Mount Point - # If we have the dummy string at the end of the duplicate - # entry, then take it off and print the original - $mnt[$i] = $1 if ($mnt[$i] =~ /^\d(.*?)--AUTOPSY--$::REG_VNAME$/o); - print "<tr>" . "<td><input type=\"radio\" name=\"vol\" value=$vol"; - print " CHECKED" if ($i == 0); - print "></td>" - . "<td><tt>" - . Print::html_encode($mnt[$i]) - . "</tt></td>"; - - # image name and ftype - print -"<td><tt>$Caseman::vol2sname{$vol}</tt></td><td>$Caseman::vol2ftype{$vol}</td>"; - if ($::LIVE == 0) { - print "<td align=center><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::VOL_DETAILS&$Args::baseargs&" - . "vol=$vol\">details</a></td>" - . "</tr>\n"; - } - else { - print "<td> </td></tr>\n"; - } - } - - # If we are done with the regular images and have some orphan - # blkls images, print them - my @sort = sort @orphan_blkls; - for (my $i = 0; $i <= $#sort; $i++) { - print -"<tr><td> </td><td> </td><td>(<input type=\"radio\" name=\"vol\" " - . "value=$sort[$i]"; - print " CHECKED" if ($#mnt == 0); - print "> unalloc)</td><td><tt>" - . Print::html_encode($Caseman::vol2sname{$sort[$i]}) - . "</tt></td><td>" - . Print::html_encode($Caseman::vol2ftype{$sort[$i]}) - . "</td></tr>\n"; - } - - # Begin Button - print "</table>\n"; - - EGRESS: - - print "<br><br>" - . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n"; - - # Ok Button - if (scalar(keys %Caseman::vol2ftype) == 0) { - print "<tr><td width=200> </td>\n"; - } - else { - print "<tr><td align=center width=200>" - . "<input type=\"image\" src=\"pict/menu_b_analyze.jpg\" " - . "alt=\"Analyze\" width=\"167\" height=20 border=0>\n" - . "</form></td>\n"; - } - - # Image Add Button - if ($::LIVE == 0) { - print "<td align=center width=200>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/menu_b_ifnew.jpg\" " - . "alt=\"Add Image\" width=167 height=20 border=0></form></td>\n" - . - - # Cancel Button - "<td align=center width=200>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::HOST_OPEN\">\n" - . "<input type=\"hidden\" name=\"case\" value=\"$Args::args{'case'}\">\n" - . "<input type=\"image\" src=\"pict/menu_b_hcls.jpg\" " - . "width=167 height=20 alt=\"Close Host\" border=0>\n" - . "</form></td></tr>"; - } - else { - print "<td width=200> </td><td width=200> </td></tr>\n"; - } - - # Help Button - print -"<td width=200> </td><td align=center width=200><a href=\"$::HELP_URL\" " - . " target=\"_blank\">" - . "<img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " - . "width=\"167\" height=20 border=0>" - . "</a></td><td width=200> </td></tr>\n" - . "</table>\n"; - - # Other features that can be done on a host - - if ($::LIVE == 0) { - print "<hr><p>" - . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" - . "<tr>\n"; - - # Timeline of file activity - print "<td align=\"center\" width=200>" - . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&" - . "mod=$::MOD_TL&view=$Timeline::FRAME\">" - . "<img border=0 " - . "src=\"pict/menu_b_tl.jpg\" " - . "width=\"167\" height=20 " - . "alt=\"File Activity Timelines\"></a></td>\n"; - - # verify the integrity of the images - print "<td align=\"center\" width=200>" - . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&" - . "mod=$::MOD_HASH&view=$Hash::IMG_LIST_FR\">" - . "<img border=0 " - . "src=\"pict/menu_b_int.jpg\" " - . "width=\"167\" height=20 " - . "alt=\"Image Integrity\"></a></td>\n" - . - - # Hashdatabases - "<td align=\"center\" width=200>" - . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&" - . "mod=$::MOD_HASH&view=$Hash::DB_MANAGER\">" - . "<img border=0 " - . "src=\"pict/menu_b_hashdb.jpg\" " - . "width=\"167\" height=20 " - . "alt=\"Hash Databases\"></a></td>\n" - . "</tr></table>\n"; - - # Notes - if ($::USE_NOTES == 1) { - print "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\">\n" - . "<tr>\n" - . "<td align=\"center\" width=300>" - . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_NORM\">" - . "<img border=0 " - . "src=\"pict/menu_b_note.jpg\" " - . "width=\"167\" height=20 " - . "alt=\"View Notes\"></a></td>\n" - . - - "<td width=300 align=\"center\">" - . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_SEQ\">" - . "<img border=0 " - . "src=\"pict/menu_b_seq.jpg\" " - . "width=\"167\" height=20 " - . "alt=\"Event Sequencer\"></a></td>\n" - . - - "</tr>\n" . "</table>\n"; - } - - # If LIVE - } - else { - print "<a href=\"./about\"><br>\n" - . "<img src=\"pict/logo.jpg\" border=0 alt=\"Logo\"></a><br>\n"; - - } - - Print::print_html_footer(); - - return 0; -} - -# Log in the host log that a given image was opened by what user -# then open the main window -sub vol_open_log { - - # These will be stopped in the func during LIVE - Print::log_host_info( - "Image $Args::args{'vol'} opened by $Args::args{'inv'}"); - Print::log_host_inv("$Args::args{'vol'}: volume opened"); - - $Args::args{'mod'} = $Args::enc_args{'mod'} = $::MOD_FRAME; - $Args::args{'view'} = $Args::enc_args{'view'} = $Frame::IMG_FRAME; - Frame::main(); -} - -# Menu to add a new image to the host -# -# The list of new images is determined by looking in the images directory -# and seeing which is not yet configured -# -sub img_add { - Print::print_html_header( - "Add Image To $Args::args{'case'}:$Args::args{'host'}"); - - print "<b>Case:</b> $Args::args{'case'}<br>\n" - . "<b>Host:</b> $Args::args{'host'}<br>\n"; - - print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD_PREP\">\n" - . Args::make_hidden(); - - print <<EOF1; -<center> -<img src=\"pict/menu_h_inew.jpg\" alt=\"Add Image\"> -<br><br><br> - -<table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> -<tr> - <td colspan=4> </td> -</tr> - -<tr> - <td align=left colspan=4> - 1. <b>Location</b><br>Enter the full path (starting with <tt>/</tt>) to the image file.<br> - If the image is split (either raw or EnCase), then enter '*' for the extension. - </td> -</tr> -<tr> - <td>  </td> - <td align=left colspan=3> - <input type=\"text\" name=\"img_path\" size=36 maxlength=256> - </td> -</tr> -<tr><td colspan=4> </td><tr> -<tr> - <td align=left colspan=4>2. <b>Type</b><br>Please select if this image file is for a disk or a single partition.</td> -</tr> -<tr> - <td>  </td> - <td align=left> - <input type=\"radio\" name=\"imgtype\" value="disk" CHECKED> - Disk - </td> - <td align=left> - <input type=\"radio\" name=\"imgtype\" value="volume"> - Partition - </td> - <td align=left>  - </td> -</tr> - -<tr><td colspan=4> </td><tr> -<tr> - <td align=left colspan=4>3. <b>Import Method</b><br>To analyze the image file, it must be located in the evidence locker. It can be imported from its current location using a symbolic link, by copying it, or by moving it. Note that if a system failure occurs during the move, then the image could become corrupt.</td> -</tr> -<tr> - <td>  </td> - <td align=left> - <input type=\"radio\" name=\"sort\" value=$IMG_ADD_SYM CHECKED> - Symlink - </td> - <td align=left> - <input type=\"radio\" name=\"sort\" value=$IMG_ADD_COPY> - Copy - </td> - <td align=left> - <input type=\"radio\" name=\"sort\" value=$IMG_ADD_MOVE> - Move - </td> -</tr> - - -<tr> - <td colspan=4> </td> -</tr> - -</table> - -<br> -<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\"> -<tr> - <td align=center colspan=2> - <input type=\"image\" src=\"pict/menu_b_next.jpg\" alt=\"Next Step\" width=\"167\" height=20 border=0> - </td> -</tr> - -</form> - -EOF1 - - print "<tr><td colspan=2> </td></tr>\n" - . "<td align=center>\n" - . " <form action=\"$::PROGNAME\" method=\"get\">\n" - . " <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . " <input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN\">\n" - . - - Args::make_hidden() - . " <input type=\"image\" src=\"pict/menu_b_cancel.jpg\" " - . "alt=\"Cancel\" width=\"167\" height=20 border=0></form>\n" - . " </td>\n" - . - - # HELP - " <td align=center>\n" - . " <a href=\"$::HELP_URL\" target=\"_blank\">\n" - . " <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" " - . "width=\"167\" height=20 border=0></a>\n" - . " </td>\n" - . "</tr>\n" - . "</table>\n"; - - Print::print_html_footer(); - - return 0; -} - -# List the images from the glob - called from img_add_prep if spl_conf is not set -sub img_add_split_conf { - my $img_path = Args::get_img_path_wild(); - my $img_type = $Args::args{'imgtype'}; - - print "<center><br><br><b>Split Image Confirmation</b><br><br>\n"; - - my @spl_img = glob($img_path); - if (scalar(@spl_img) == 0) { - print "No images were found at this location ($img_path)<br>\n" - . "Use the back button and fix the path<br>\n"; - return; - } - - print <<EOF1; -The following images will be added to the case.<br> -If this is not the correct order, then you should change the naming convention.<br> -Press the Next button at the bottom of the page if this is correct.<br><br> - -<table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> -<tr> - <td colspan=2> </td> -</tr> -EOF1 - - my $a = 0; - foreach $i (@spl_img) { - - # We need to do this when we analyze the image, so do it here too to show - # what will be analyzed - $i = $1 if ($i =~ /^($::REG_IMG_PATH)$/); - print -"<tr><td align=\"center\">$a</td><td align=\"left\"><tt>$i</tt></td></tr>\n"; - $a++; - } - - my $vs = ""; - $vs = "&vstype=$Args::args{'vstype'}" - if (exists $Args::args{'vstype'}); - - # Print the Ok Button - print "</table><br><br>\n" - . "<table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" border=0>" - . "<tr><td width=\"300\" align=\"center\"><a href=\"$::PROGNAME?${Args::baseargs_novol}&" - . "mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD_PREP&spl_conf=1&sort=$Args::args{'sort'}&" - . "img_path=$img_path&imgtype=$Args::args{'imgtype'}$vs\">" - . "<img src=\"pict/menu_b_next.jpg\" alt=\"Next\" " - . "width=\"167\" height=20 border=0></a></td>\n" - . "<td width=\"300\" align=\"center\"><a href=\"$::PROGNAME?${Args::baseargs_novol}&" - . "mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD\">" - . "<img src=\"pict/menu_b_cancel.jpg\" alt=\"cancel\" width=\"167\" height=\"20\" border=\"0\">" - . "</a></td></tr></table>\n"; - - return 0; -} - -# Run the autodetect stuff and get confirmation from the user -sub img_add_prep { - Args::check_img_path_wild(); - Args::check_sort(); - unless ((exists $Args::args{'imgtype'}) - && ($Args::args{'imgtype'} =~ /^\w+$/)) - { - Print::print_check_err("Invalid image type"); - } - - Print::print_html_header("Collecting details on new image file"); - - my $img_path = Args::get_img_path_wild(); - - my $img_type = $Args::args{'imgtype'}; - my $spl_conf = 0; - $spl_conf = 1 - if ((exists $Args::args{'spl_conf'}) && ($Args::args{'spl_conf'} == 1)); - - # If we have a wildcard then it is a split image, so we verify it first and - # then make a string of the images so we can test it. - if ($img_path =~ /[\*\?]/) { - if ($spl_conf == 0) { - return img_add_split_conf(); - } - else { - $img_tmp = ""; - foreach my $i (glob($img_path)) { - if ($i =~ /^($::REG_IMG_PATH)$/) { - $img_tmp .= "\"$1\" "; - } - } - $img_path = $img_tmp; - } - } - else { - unless ((-f $img_path) - || (-d $img_path) - || (-l $img_path) - || (-b $img_path) - || (-c $img_path)) - { - Print::print_err("Image file not found ($img_path)"); - } - $img_path = "\"$img_path\""; - } - - # Get the image type - local *OUT; - Exec::exec_pipe(*OUT, "'$::TSKDIR/img_stat' -t $img_path"); - my $itype = Exec::read_pipe_line(*OUT); - if (defined $itype) { - chomp $itype; - $itype = $1 if ($itype =~ /^(\w+)$/); - } - else { - print -"The image format type could not be determined for this image file<br>\n"; - return; - } - close(OUT); - - # The plan here is to collect the needed info and then we print it - - my $conflict = 0; - my $cnt = 0; - $start[0] = ""; - $end[0] = ""; - $type[0] = ""; - $desc[0] = ""; - $active[0] = ""; - - my $vstype = ""; - - my $vstype_flag = ""; - my $mmls_out = ""; # Will contain output of mmls (if disk image) - if ($img_type eq "disk") { - my $out; - - if ( (exists $Args::args{'vstype'}) - && ($Args::args{'vstype'} =~ /^(\w+)$/)) - { - $vstype = $Args::args{'vstype'}; - $vstype_flag = "-t $vstype"; - } - - # Get the type - else { - - Exec::exec_pipe(*OUT, "'$::TSKDIR/mmstat' -i $itype $img_path"); - - $vstype = Exec::read_pipe_line(*OUT); - close(OUT); - - chomp $vstype if (defined $vstype); - - if ( (!defined $vstype) - || ($vstype =~ /^Error determining/) - || ($vstype eq "") - || (!exists $Vs::type{$vstype}) - || ($vstype !~ /^\w+$/)) - { - print -"<table><tr><td colspan=2><font color=\"$::DEL_COLOR[0]\">Warning:</font> Autopsy could not determine the volume system type for the disk image (i.e. the type of partition table).<br>\n" - . "Please select the type from the list below or reclassify the image as a volume image instead of as a disk image.</td></tr>\n" - . "<tr><td colspan=2> </td></tr>\n" - . "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD_PREP\">\n" - . "<input type=\"hidden\" name=\"spl_conf\" value=\"1\">\n" - . "<input type=\"hidden\" name=\"img_path\" value=\"$Args::args{'img_path'}\">\n" - . "<input type=\"hidden\" name=\"sort\" value=\"$Args::enc_args{'sort'}\">\n" - . Args::make_hidden() - . "<tr><td>Disk Image <input type=\"radio\" name=\"imgtype\" value=\"disk\" CHECKED></td>\n" - . "<td>Volume Image<input type=\"radio\" name=\"imgtype\" value=\"volume\"></td></tr>\n" - . "<tr><td>Volume System Type (disk image only): <select name=\"vstype\">\n"; - - foreach my $vs (sort keys %Vs::type) { - print "<option value=\"$vs\""; - print " selected" if ($vs eq 'dos'); - print ">${vs}</option>\n"; - } - - print "</select></td>" - . "<td> </td></tr>" - . "<tr><td colspan=2> </td></tr>" - . "</table><br><br>\n" - . "<input type=\"image\" src=\"pict/menu_b_ok.jpg\" alt=\"Ok\" width=\"176\" height=20 border=0>" - . "</form>\n"; - return; - } - $vstype = $1 if ($vstype =~ /^(\w+)$/); - $vstype_flag = "-t $vstype"; - } - - # Run 'mmls' on the image - Exec::exec_pipe(*OUT, - "'$::TSKDIR/mmls' -a -i $itype -aM $vstype_flag -r $img_path"); - - # cycle through results and add each to table with file system type - my $part_type = ""; - - while ($_ = Exec::read_pipe_line(*OUT)) { - $mmls_out .= "$_"; # Save the line - last if (/^Error determining partition/); - - if (/^\d+:\s+[\d:]+\s+(\d+)\s+(\d+)\s+\d+\s+(\S.*)$/) { - $start[$cnt] = $1; - $end[$cnt] = $2; - $desc[$cnt] = $3; - $active[$cnt] = 1; - } - elsif ((/^DOS Partition/) - || (/^BSD Disk/) - || (/^Sun VTOC/) - || (/^MAC Partition/) - || (/^GUID Partition/)) - { - $part_type = $_; - - #print "<tr><td colspan=7> </td></tr>\n"; - #print "<tr><td colspan=7>$_</td></tr>\n"; - next; - } - elsif (/^Sector:/) { - - #print "<tr><td colspan=7>$_</td></tr>\n"; - next; - } - else { - next; - } - - # Skip the BSD partition for the full disk - next - if ( ($part_type =~ /^BSD Disk/) - && ($start[$cnt] == 0) - && ($desc[$cnt] =~ /^Unused/)); - - # Skip if this is an extended DOS partition - next - if ( ($part_type =~ /^DOS Partition/) - && ($desc[$cnt] =~ /Extended \(/)); - - # Get rid of the leading 0s - $start[$cnt] = $1 - if ($start[$cnt] =~ /^0+([1-9]\d*)$/); - $end[$cnt] = $1 - if ($end[$cnt] =~ /^0+([1-9]\d*)$/); - - # Do we already have this partition? - my $i; - for ($i = 0; $i < $cnt; $i++) { - next if ($active[$i] == 0); - - if ($start[$i] == $start[$cnt]) { - $conflict = 1; - - if ($end[$i] == $end[$cnt]) { - last; - } - - #The previous was the BSD partition - skip it */ - if ( ($desc[$i] =~ /^FreeBSD \(0xA5\)/) - || ($desc[$i] =~ /^OpenBSD \(0xA6\)/) - || ($desc[$i] =~ /^NetBSD \(0xA9\)/)) - { - $active[$i] = 0; - - # if the current one is the BSD partition for - # the full partition/disk then skip it - if ($desc[$cnt] =~ /^Unused /) { - $active[$cnt] = 0; - } - } - } - - # Do we start inside of another? - if (($start[$i] > $start[$cnt]) && ($end[$i] < $start[$cnt])) { - $conflict = 1; - } - - # Do we end inside of another? - elsif (($start[$i] < $end[$cnt]) && ($end[$i] > $end[$cnt])) { - $conflict = 1; - } - } - if (($end[$i] == $end[$cnt]) && ($i != $cnt)) { - next; - } - - local *OUT2; - my $out2; - - # Run 'fstat -t' on the image - Exec::exec_pipe(*OUT2, - "'$::TSKDIR/fsstat' -o $start[$cnt] -i $itype -t $img_path"); - - $type[$cnt] = Exec::read_pipe_line(*OUT2); - close(OUT2); - - if ( (!exists $type[$cnt]) - || (!defined $type[$cnt]) - || ($type[$cnt] =~ /^Cannot determine/) - || ($type[$cnt] eq "")) - { - $type[$cnt] = "Unknown"; - } - chomp $type[$cnt]; - - $cnt++; - } - close(OUT); - - if ($conflict == 1) { - print -"<tr><td colspan=2><font color=\"$::DEL_COLOR[0]\">Warning:</font> Conflicts in the partitions were detected.<br>The full <tt>mmls</tt> output is given at the bottom of the page</td></tr>\n" - . "<tr><td colspan=2> </td></tr>\n"; - } - } - - # If a volume, then run fsstat on it - elsif ($img_type eq "volume") { - - # Run 'fstat -t' on the image - Exec::exec_pipe(*OUT, "'$::TSKDIR/fsstat' -t -i $itype $img_path"); - - $type[0] = Exec::read_pipe_line(*OUT); - close(OUT); - - if ( (!defined $type[0]) - || ($type[0] =~ /^Cannot determine/) - || ($type[0] eq "")) - { - $type[0] = "Unknown"; - print -"<font color=\"$::DEL_COLOR[0]\">Warning:</font> The file system type of the volume image file could not be determined.<br>\n" - . "If this is a disk image file, return to the previous page and change the type.<br><br>\n"; - } - chomp $type[0]; - $start[0] = 0; - $end[0] = 0; - $active[0] = 1; - $desc[0] = $type[0]; - $cnt++; - close(OUT); - } - else { - Print::print_err("Unknown image type: $img_type"); - } - - my $sname = $img_path; - $sname = "$::IMGDIR/" . "$1" if ($sname =~ /\/($::REG_FILE)\"$/); - -# Now that we have the information about the partitions and disks, print the fields - print <<EOF1; - -<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\"> -<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> -<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_ADD_DOIT\"> -<input type=\"hidden\" name=\"img_path\" value=\"$Args::args{'img_path'}\"> -<input type=\"hidden\" name=\"num_img\" value=\"$cnt\"> -<input type=\"hidden\" name=\"sort\" value=\"$Args::enc_args{'sort'}\"> - - -<center> -<h3>Image File Details</h3> -<table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> -<tr> - <td align=left colspan=4> - <b>Local Name: </b> $sname - </td> -</tr> - -EOF1 - - # We do not currently offer integrity options for non-raw files - if (($itype eq "raw") || ($itype eq "split")) { - - print <<EOF1b; -<tr> - <td align=left colspan=4> - <b>Data Integrity: </b> An MD5 hash can be used to verify the - integrity of the image. (With split images, this hash is for the full image file) - </td> -</tr> - -<tr> - <td>  </td> - <td align=left colspan=3> - <input type=\"radio\" name=\"do_md5\" value=\"$MD5_NOTHING\" CHECKED> - <u>Ignore</u> the hash value for this image. - </td> -</tr> - -<tr> - <td>  </td> - <td align=left colspan=3> - <input type=\"radio\" name=\"do_md5\" value=\"$MD5_CALC\"> - <u>Calculate</u> the hash value for this image. - </td> -</tr> - -<tr> - <td>  </td> - <td align=left colspan=3> - <input type=\"radio\" name=\"do_md5\" value=\"$MD5_ADD\"> - <u>Add</u> the following MD5 hash value for this image: - </td> -</tr> - -<tr> - <td>  </td> - <td align=left colspan=3>     - <input type=\"text\" name=\"md5\" size=36 maxlength=32> - </td> -</tr> - -<tr> - <td>  </td> - <td align=left colspan=3>     - <input type=\"checkbox\" name=\"ver_md5\" value=\"1\"> -  Verify hash after importing? - </td> -</tr> -EOF1b - } - else { - print - "<input type=\"hidden\" name=\"do_md5\" value=\"$MD5_NOTHING\">\n"; - } - - print <<EOF1c; -</table> - -<h3>File System Details</h3> -<table width=\"600\" cellpadding=\"2\" cellspacing=\"0\" background=\"$::YEL_PIX\" border=0> - -<tr> - <td colspan=2 align=left>Analysis of the image file shows the following partitions:</td> -</tr> -<tr> - <td colspan=2> </td> -</tr> - -EOF1c - - print Args::make_hidden(); - - print "<input type=\"hidden\" name=\"vstype\" value=\"$vstype\">\n" - if ($vstype ne ""); - - my $idx = 1; - my $ms_cnt = 0; - my @ms_name = ("C:", "D:", "E:", "F:", "G:", "H:", "I:", "J:"); - for (my $i = 0; $i < $cnt; $i++) { - next if ($active[$i] == 0); - print -"<tr><td colspan=2><u>Partition $idx</u> (Type: $desc[$i])</td><tr>\n"; - - if ($cnt > 1) { - print "<tr><td colspan=2>  Add to case? " - . "<input type=\"checkbox\" name=\"yes-${idx}\" value=1 CHECKED></td></tr>\n"; - } - else { - print "<input type=\"hidden\" name=\"yes-${idx}\" value=1>\n"; - } - - unless (($start[$i] == 0) && ($end[$i] == 0)) { - print "<tr><td colspan=2>  Sector Range: " - . "$start[$i] to $end[$i]" - . "</td></tr>\n"; - } - - print - "<input type=\"hidden\" name=\"start-${idx}\" value=\"$start[$i]\">" - . "<input type=\"hidden\" name=\"end-${idx}\" value=\"$end[$i]\">\n" - . "<tr><td>  Mount Point: <input type=\"text\" name=\"mnt-${idx}\" size=\"6\""; - if (($type[$i] =~ /^ntfs/) || ($type[$i] =~ /^fat/)) { - print " value=\"$ms_name[$ms_cnt]\"" - if ($ms_cnt < 8); - $ms_cnt++; - } - elsif (($type[$i] =~ /^raw/) - || ($type[$i] =~ /^swap/)) - { - print " value=\"N/A\""; - } - else { - print " value=\"/$idx/\""; - } - print "></td>\n" - . "<td>File System Type: <select name=\"ftype-${idx}\">\n"; - - foreach my $fs (@Fs::types) { - print "<option value=\"$fs\""; - print " selected" if ($fs eq $type[$i]); - print ">${fs}</option>\n"; - } - - # The following do not have 'metas' but should be in the list - print "<option value=\"\">======</option>\n"; - if ($type[$i] eq "Unknown") { - print "<option value=\"raw\" selected>raw</option>\n"; - } - else { - print "<option value=\"raw\">raw</option>\n"; - } - - print "<option value=\"swap\">swap</option>\n" - . "</select></td></tr>\n" - . "<tr><td colspan=2> </td></tr>\n"; - - $idx++; - } - - print "</table>\n"; - - print <<EOF2; -<br><br> -<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\"> -<tr> - <td align=center> - <input type=\"image\" src=\"pict/menu_b_add.jpg\" - alt=\"Add\" width=\"176\" height=20 border=0> - </td> -</form> - <td align=center> - <form action=\"$::PROGNAME\" method=\"get\"> -EOF2 - print Args::make_hidden(); - print <<EOF3; - <input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\"> - <input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN\"> - <input type=\"image\" src=\"pict/menu_b_cancel.jpg\" - alt=\"Cancel\" width=\"167\" height=20 border=0> - </form> - </td> - <td align=center><a href=\"$::HELP_URL\" - target=\"_blank\"> - <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" - width=\"167\" height=20 border=0></a> - </td> -</tr> -</table> -EOF3 - - if ($img_type eq "disk") { - print -"</center><p>For your reference, the <tt>mmls</tt> output was the following:<br><pre>$mmls_out</pre>\n"; - } - - Print::print_html_footer(); - - return 0; -} - -# Add the image to the configuration by adding it to the host config file -# and the md5.txt file if that data was provided -sub img_add_doit { - - Args::check_num_img(); - Args::check_img_path_wild(); - Args::check_sort(); - Args::check_do_md5(); - - my $num_img = Args::get_num_img(); - my $img_path = Args::get_img_path_wild(); - my $import_type = Args::get_sort(); - - Print::print_html_header("Add a new image to an Autopsy Case"); - - my $err = 0; - my $add_num = 0; - $start[0] = 0; - $end[0] = 0; - $ftype[0] = ""; - $mnt[0] = ""; - - # We need a string with all images in it for the hashes and file system testing - my $img_path_full; - if ($img_path =~ /[\*\?]/) { - $img_path_full = ""; - foreach my $i (glob($img_path)) { - if ($i =~ /^($::REG_IMG_PATH)$/) { - $img_path_full .= "\"$1\" "; - } - } - } - else { - $img_path_full = "\"$img_path\""; - } - - # Get the image type - local *OUT; - Exec::exec_pipe(*OUT, "'$::TSKDIR/img_stat' -t $img_path_full"); - my $itype = Exec::read_pipe_line(*OUT); - if (defined $itype) { - chomp $itype; - $itype = $1 if ($itype =~ /^(\w+)$/); - } - else { - print -"The image format type could not be determined for this image file<br>\n"; - return; - } - close(OUT); - - # Check the hash of the image if that is the plan - my $do_md5 = Args::get_do_md5(); - my $act_md5 = ""; - unless ($do_md5 == $MD5_NOTHING) { - - # Do we need to calculate an MD5? - if ( - ($do_md5 == $MD5_CALC) - || ( ($do_md5 == $MD5_ADD) - && (exists $Args::args{'ver_md5'}) - && ($Args::args{'ver_md5'} == 1)) - ) - { - - print "<p>Calculating MD5 (this could take a while)<br>\n"; - $act_md5 = Hash::calc_md5_split($img_path_full); - unless ($act_md5 =~ /^$::REG_MD5$/o) { - print "Error calculating MD5: $act_md5<br>\n"; - return 1; - } - print "Current MD5: <tt>$act_md5</tt><br>\n"; - } - - # And md5 value was given so we can add it to the md5.txt file - if (($do_md5 == $MD5_ADD) && (exists $Args::args{'md5'})) { - - my $md5 = $Args::args{'md5'}; - unless ($md5 =~ /^$::REG_MD5$/o) { - if ($md5 eq "") { - print "MD5 value missing<br>\n"; - } - else { - print "Invalid MD5 value (32 numbers or letters a-f)<br>\n"; - } - print "<p><a href=\"$::PROGNAME?" - . "mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD&" - . "$Args::baseargs\">" - . "<img src=\"pict/menu_b_back.jpg\" border=\"0\" " - . "width=\"167\" height=20 alt=\"Back\"></a>\n"; - return 1; - } - $md5 =~ tr/[a-f]/[A-F]/; - - # They also want us to validate the MD5 - if ( (exists $Args::args{'ver_md5'}) - && ($Args::args{'ver_md5'} == 1)) - { - - if ($act_md5 eq $md5) { - print "Integrity Check Passed<br>\n"; - Print::log_host_info("Integrity check passed on new image"); - } - else { - print "<font color=\"$::DEL_COLOR[0]\">" - . "Integrity Check Failed<br></font><br>\n" - . "Provided: <tt>$md5</tt><br>\n" - . "Image not added to case<br>\n"; - - Print::log_host_info("Integrity check failed on new image"); - return 1; - } - } - - # set the act_md5 value to what was given and verified - $act_md5 = $md5; - } - - # We will add the MD5 to the config file after we get its ID - } - - # Proces the image arguments to make sure they are all there and test the - # file system type - print "Testing partitions<br>\n"; - for (my $i = 0; $i <= $num_img; $i++) { - - next - unless ((exists $Args::args{"yes-" . $i}) - && ($Args::args{"yes-" . $i} == 1)); - - if ( (exists $Args::args{"start-" . $i}) - && ($Args::args{"start-" . $i} =~ /^(\d+)$/)) - { - $start[$add_num] = $1; - } - else { - print "Missing starting address for partition $i<br>\n"; - $err = 1; - last; - } - - if ( (exists $Args::args{"end-" . $i}) - && ($Args::args{"end-" . $i} =~ /^(\d+)$/)) - { - $end[$add_num] = $1; - } - else { - print "Missing ending address for partition $i<br>\n"; - $err = 1; - last; - } - - if ( (exists $Args::args{"mnt-" . $i}) - && ($Args::args{"mnt-" . $i} =~ /^($::REG_MNT)$/)) - { - $mnt[$add_num] = $1; - } - else { - print "Missing mount point for partition $i<br>\n"; - $err = 1; - last; - } - - if ( (exists $Args::args{"ftype-" . $i}) - && ($Args::args{"ftype-" . $i} =~ /^($::REG_FTYPE)$/)) - { - $ftype[$add_num] = $1; - } - else { - print "Missing file system type for partition $i<br>\n"; - $err = 1; - last; - } - - # Test the File System - if (($ftype[$add_num] ne 'swap') && ($ftype[$add_num] ne 'raw')) { - - local *OUT; - my $out; - - # Run 'fsstat' and see if there is any output - else there was - # an error and the data went to STDERR - Exec::exec_pipe(*OUT, -"'$::TSKDIR/fsstat' -o $start[$add_num] -i $itype -f $ftype[$add_num] $img_path_full" - ); - unless (read(OUT, $out, 1)) { - print -"<p>Partition $i is not a <tt>$ftype[$add_num]</tt> file system<br>\n"; - $err = 1; - last; - } - close(OUT); - } - $add_num++; - } - - # Go back if we got an error - if ($err == 1) { - print "Use the browser's back button to fix the data<br>\n"; - return 1; - } - - ################################################## - # Copy the images and add them to the config file - - if ($import_type == $IMG_ADD_SYM) { - Print::print_err("ERROR: /bin/ln missing") - unless (-x '/bin/ln'); - - print "Linking image(s) into evidence locker<br>\n"; - } - elsif ($import_type == $IMG_ADD_COPY) { - Print::print_err("ERROR: /bin/cp missing") - unless (-x '/bin/cp'); - - print -"Copying image(s) into evidence locker (this could take a little while)<br>\n"; - } - elsif ($import_type == $IMG_ADD_MOVE) { - Print::print_err("ERROR: /bin/mv missing") - unless (-x '/bin/mv'); - - print "Moving image(s) into evidence locker<br>\n"; - } - else { - Print::print_err("Invalid Import Type: $import_type\n"); - } - - my $imgid = ""; - foreach my $i (glob($img_path)) { - - # remove the tainting - $i = $1 if ($i =~ /^($::REG_IMG_PATH)$/); - - # Deterine the local (target) name - my $img = ""; - if ($i =~ /\/($::REG_FILE)$/) { - $img = "$::IMGDIR/$1"; - } - else { - Print::print_err("Error Parsing Image Path ($i)\n"); - } - - # Get the full path of the destination - my $img_dst = "$::host_dir" . "$img"; - if ((-e "$img_dst") || (-l "$img_dst")) { - Print::print_err( -"An image by the same name already exists in the Host directory ($img)\n" - . "Use the browser's back button to fix the name or delete the existing file." - ); - } - - my $orig_size = (stat("$i"))[7]; - - # Copy, Move, or link it - if ($import_type == $IMG_ADD_SYM) { - - Print::log_host_info( -"Sym Linking image $img_path into $Args::args{'case'}:$Args::args{'host'}" - ); - - Exec::exec_sys("/bin/ln -s '$i' '$img_dst'"); - } - elsif ($import_type == $IMG_ADD_COPY) { - Print::log_host_info( -"Copying image $img_path into $Args::args{'case'}:$Args::args{'host'}" - ); - - Exec::exec_sys("/bin/cp '$i' '$img_dst'"); - } - elsif ($import_type == $IMG_ADD_MOVE) { - Print::log_host_info( -"Moving image $img_path into $Args::args{'case'}:$Args::args{'host'}" - ); - - Exec::exec_sys("/bin/mv '$i' '$img_dst'"); - } - - my $new_size = (stat("$img_dst"))[7]; - - if ($new_size != $orig_size) { - Print::print_err( -"Original image size ($orig_size) is not the same as the destination size ($new_size)" - ); - } - - # Add the disk and partition images to the config file - $imgid = Caseman::add_img_host_config("image", "$itype $img", $imgid); - } - print "Image file added with ID <tt>$imgid</tt><br>\n"; - - # AFM files have raw files that we also need to copy - # This approach is not the best, since it may copy more than - # is needed - if ($itype eq "afm") { - my $afm_base_path = ""; - - if ($img_path =~ /^(.*?)\.afm/i) { - $afm_base_path = $1; - $afm_base_path .= ".[0-9][0-9][0-9]"; - } - else { - Print::print_err( - "Error parsing out base name of AFM file $img_path"); - } - - print "BASE: $afm_base_path<br>\n"; - - my $copied = 0; - - foreach my $i (glob($afm_base_path)) { - $copied++; - - # remove the tainting - $i = $1 if ($i =~ /^($::REG_IMG_PATH)$/); - - # Deterine the local (target) name - my $img = ""; - if ($i =~ /\/($::REG_FILE)$/) { - $img = "$::IMGDIR/$1"; - } - else { - Print::print_err("Error Parsing Image Path ($i)\n"); - } - - # Get the full path of the destination - my $img_dst = "$::host_dir" . "$img"; - if ((-e "$img_dst") || (-l "$img_dst")) { - Print::print_err( -"An image by the same name already exists in the Host directory ($img) (AFM import)\n" - . "Use the browser's back button to fix the name or delete the existing file." - ); - } - - my $orig_size = (stat("$i"))[7]; - - # Copy, Move, or link it - if ($import_type == $IMG_ADD_SYM) { - - Print::log_host_info( -"Sym Linking image $img_path into $Args::args{'case'}:$Args::args{'host'}" - ); - - Exec::exec_sys("/bin/ln -s '$i' '$img_dst'"); - } - elsif ($import_type == $IMG_ADD_COPY) { - Print::log_host_info( -"Copying image $img_path into $Args::args{'case'}:$Args::args{'host'}" - ); - - Exec::exec_sys("/bin/cp '$i' '$img_dst'"); - } - elsif ($import_type == $IMG_ADD_MOVE) { - Print::log_host_info( -"Moving image $img_path into $Args::args{'case'}:$Args::args{'host'}" - ); - - Exec::exec_sys("/bin/mv '$i' '$img_dst'"); - } - - my $new_size = (stat("$img_dst"))[7]; - - if ($new_size != $orig_size) { - Print::print_err( -"Original image size ($orig_size) is not the same as the destination size ($new_size) after AFM import" - ); - } - } - if ($copied == 0) { - Print::print_err( -"No AFM raw files were found with the same base name and a numeric extension" - ); - } - else { - print "$copied AFM raw files imported<br>\n"; - } - } - - Caseman::update_md5("$imgid", "$act_md5") - unless (($do_md5 == $MD5_NOTHING) || ($imgid eq "")); - - # Add a disk entry if the image is of a disk - unless (($add_num == 1) && ($end[0] == 0) && ($start[0] == 0)) { - unless ((exists $Args::args{'vstype'}) - && ($Args::args{'vstype'} =~ /^(\w+)$/)) - { - Print::print_err("Missing Volume System Type"); - } - my $vstype = $Args::args{'vstype'}; - - my $diskid = Caseman::add_vol_host_config("disk", "$imgid $vstype"); - print "<p>Disk image (type $vstype) added with ID <tt>$diskid</tt>\n"; - } - - # Add the file system / partition entries - for (my $i = 0; $i < $add_num; $i++) { - my $volid = - Caseman::add_vol_host_config("part", - "$imgid $start[$i] $end[$i] $ftype[$i] $mnt[$i]"); - print -"<p>Volume image ($start[$i] to $end[$i] - $ftype[$i] - $mnt[$i]) added with ID <tt>$volid</tt>\n"; - } - - print <<EOF; -<p> -<center> -<table width=600> -<tr> - <td width=300 align=center> - <a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::VOL_OPEN&${Args::baseargs_novol}\"> - <img src=\"pict/menu_b_ok.jpg\" alt=\"Ok\" width=\"167\" height=20 border=\"0\"> - </a> - </td> - <td width=300 align=center> - <a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::IMG_ADD&${Args::baseargs_novol}\"> - <img src=\"pict/menu_b_inew.jpg\" alt=\"Ok\" width=\"167\" height=20 border=\"0\"> - </a> - </td> -</tr> -</table> -</center> - -EOF - Print::print_html_footer(); - - return 0; -} - -# Display details of image based on config values -# provides links to remove the config of the image and to get the file -# system details - -sub vol_details { - Print::print_html_header("Details of $Args::args{'vol'}"); - - Args::get_unitsize(); - - my $vol = Args::get_vol('vol'); - - my $mnt = $Caseman::vol2mnt{$vol}; - my $ftype = $Caseman::vol2ftype{$vol}; - - print "<center>" - . "<img src=\"pict/menu_h_idet.jpg\" alt=\"Image Details\">" - . "<br><br><br>\n" - . "<table width=\"600\" cellspacing=\"0\" cellpadding=\"2\" " - . "background=\"$::YEL_PIX\" border=0>\n" - . " <tr><td colspan=\"2\"> </td></tr>\n" - . - - # Name - " <tr><td align=\"right\" width=\"300\"><b>Name:</b></td>" - . "<td align=\"left\"><tt>$Caseman::vol2sname{$vol}</tt></td></tr>\n" - . "<tr><td align=\"right\" width=\"300\"><b>Volume Id:</b></td>" - . "<td align=\"left\"><tt>$vol</tt></td></tr>\n" - . "<tr><td align=\"right\" width=\"300\"><b>Parent Volume Id:</b></td>" - . "<td align=\"left\"><tt>$Caseman::vol2par{$vol}</tt></td></tr>\n" - . "<tr><td align=\"right\" width=\"300\"><b>Image File Format:</b></td>" - . "<td align=\"left\"><tt>$Caseman::vol2itype{$vol}</tt></td></tr>\n" - - # Mount - . " <tr><td align=\"right\"><b>Mounting Point:</b></td>" - . "<td align=\"left\"><tt>$mnt</tt></td></tr>\n" - . - - # Type - " <tr><td align=\"right\"><b>File System Type:</b></td>" - . "<td align=\"left\"><tt>$ftype</tt></td></tr>\n"; - - # Host Directory - print " <tr><td colspan=\"2\"> </td></tr>\n" - - # Strings File - . " <tr><td colspan=2 align=\"center\"><b>External Files</b></td></tr>\n" - . " <tr><td align=\"right\"><b>ASCII Strings:</b></td>" - . "<td align=\"left\"><tt>" - . ( - (exists $Caseman::vol2str{$vol}) - ? $Caseman::vol2sname{$Caseman::vol2str{$vol}} - : " " - ) - . "</tt></td></tr>\n" - . - - # Unicode Strings File - " <tr><td align=\"right\"><b>Unicode Strings:</b></td>" - . "<td align=\"left\"><tt>" - . ( - (exists $Caseman::vol2uni{$vol}) - ? $Caseman::vol2sname{$Caseman::vol2uni{$vol}} - : " " - ) - . "</tt></td></tr>\n"; - - if (($ftype ne "raw") && ($ftype ne "swap")) { - - # blkls file - print -" <tr><td align=\"right\"><b>Unallocated $Fs::addr_unit{$ftype}s:</b></td>" - . "<td align=\"left\"><tt>" - . ( - (exists $Caseman::vol2blkls{$vol}) - ? $Caseman::vol2sname{$Caseman::vol2blkls{$vol}} - : " " - ) - . "</tt></td></tr>\n"; - - # Strings of blkls - print - " <tr><td align=\"right\"><b>ASCII Strings of Unallocated:</b></td>" - . "<td align=\"left\"><tt>" - . ( - ( - (exists $Caseman::vol2blkls{$vol}) - && (exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}}) - ) - ? $Caseman::vol2sname{$Caseman::vol2str{$Caseman::vol2blkls{$vol}}} - : " " - ) - . "</tt></td></tr>\n"; - - # Unicodde Strings of blkls - print -" <tr><td align=\"right\"><b>Unicode Strings of Unallocated:</b></td>" - . "<td align=\"left\"><tt>" - . ( - ( - (exists $Caseman::vol2blkls{$vol}) - && (exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}) - ) - ? $Caseman::vol2sname{$Caseman::vol2uni{$Caseman::vol2blkls{$vol}}} - : " " - ) - . "</tt></td></tr>\n"; - } - - print " <tr><td colspan=\"2\"> </td></tr>\n" - . "</table>\n<a name=\"extract\"\n"; - - # Section for Strings file and 'blkls' file - - if ( - (!(exists $Caseman::vol2str{$vol})) - || (!(exists $Caseman::vol2uni{$vol})) - || (!(exists $Caseman::vol2blkls{$vol})) - || ( - (exists $Caseman::vol2blkls{$vol}) - && ( (!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) - || (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}))) - ) - ) - { - print "<hr><table width=600>\n<tr>"; - } - - # Strings File - if ( (!(exists $Caseman::vol2str{$vol})) - || (!(exists $Caseman::vol2uni{$vol}))) - { - - print -"<td align=\"center\" width=280><h3>Extract Strings of<br>Entire Volume</h3>" - . "Extracting the ASCII and Unicode strings from a file system will " - . "make keyword searching faster.<br><br>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "Generate MD5? " - . "<input type=\"checkbox\" name=\"md5\" value=\"1\" CHECKED><br><br>" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_MAKESTR\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n" - . Args::make_hidden(); - - if (!(exists $Caseman::vol2str{$vol})) { - print -"ASCII: <input type=\"checkbox\" name=\"str\" value=\"1\" CHECKED> \n"; - } - if (!(exists $Caseman::vol2uni{$vol})) { - print -" Unicode: <input type=\"checkbox\" name=\"uni\" value=\"1\" CHECKED>\n"; - } - - print "<br><br><input type=\"image\" src=\"pict/srch_b_str.jpg\" " - . "alt=\"Extract Strings\" border=\"0\">\n</form></td>\n" - . "<td width=40> </td>\n"; - } - - if (($ftype eq 'blkls') || ($ftype eq 'swap') || ($ftype eq 'raw')) { - - # Place holder for types that have no notion of unallocated - } - - # Unallocated Space File - elsif (!(exists $Caseman::vol2blkls{$vol})) { - - print -"<td align=\"center\" width=280><h3>Extract Unallocated $Fs::addr_unit{$ftype}s</h3>" - . "Extracting the unallocated data in a file system allows " - . "more focused keyword searches and data recovery.<br><br>\n" - . "(Note: This Does Not Include Slack Space)<br>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n"; - - print "Generate MD5? " - . "<input type=\"checkbox\" name=\"md5\" value=\"1\" CHECKED><br><br>" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_MAKEBLKLS\">\n" - . - - "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/srch_b_un.jpg\" " - . "alt=\"Extract Unallocated Data\" border=\"0\">\n<br></form>\n"; - } - - # strings of 'blkls' - elsif ((!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) - || (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}))) - { - - print -"<td align=\"center\" width=280><h3>Extract Strings of<br>Unallocated $Fs::addr_unit{$ftype}s</h3>" - . "Extracting the ASCII strings from the unallocated data will make " - . "keyword searching faster.<br><br>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "Generate MD5? " - . "<input type=\"checkbox\" name=\"md5\" value=\"1\" CHECKED><br><br>" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_MAKESTR\">\n" - . - -"<input type=\"hidden\" name=\"vol\" value=\"$Caseman::vol2blkls{$vol}\">\n" - . "<input type=\"hidden\" name=\"fname_mode\" value=\"$FNAME_MODE_INIT\">\n" - . Args::make_hidden(); - - if (!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) { - print -"ASCII: <input type=\"checkbox\" name=\"str\" value=\"1\" CHECKED> \n"; - } - if (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}})) { - print -" Unicode: <input type=\"checkbox\" name=\"uni\" value=\"1\" CHECKED>\n"; - } - print "<br><br><input type=\"image\" src=\"pict/srch_b_str.jpg\" " - . "alt=\"Extract Strings\" border=\"0\">\n</form></td>\n"; - } - if ( - (!(exists $Caseman::vol2str{$vol})) - || (!(exists $Caseman::vol2uni{$vol})) - || (!(exists $Caseman::vol2blkls{$vol})) - || ( - (exists $Caseman::vol2blkls{$vol}) - && ( (!(exists $Caseman::vol2str{$Caseman::vol2blkls{$vol}})) - || (!(exists $Caseman::vol2uni{$Caseman::vol2blkls{$vol}}))) - ) - ) - { - print "</tr></table><hr>\n"; - } - - print "<p>" - . "<table width=\"400\" cellspacing=\"0\" cellpadding=\"2\">\n" - . - - # Ok - "<tr><td align=center width=200>" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_OPEN\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/menu_b_close.jpg\" " - . "alt=\"Close\" width=\"167\" height=20 border=0></form></td>\n"; - - print "<td align=center width=200>"; - if (($ftype ne "raw") && ($ftype ne "swap")) { - - # File System Details - print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_blank\">\n" - . Args::make_hidden() - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" - . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_FS\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . "<input type=\"image\" src=\"pict/menu_b_fs.jpg\" " - . "width=167 height=20 " - . "alt=\"File System\" border=0></form></td>\n"; - } - else { - print " </td>\n"; - } - -# Remove Image -# THis was removed 12/03 because it causes problems because the image still -# exists and config entries and ... it becomes a mess -# print -# "<td align=center width=200>". -# "<form action=\"$::PROGNAME\" method=\"get\">\n". -# "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n". -# "<input type=\"hidden\" name=\"view\" value=\"$Caseman::IMG_DEL\">\n". -# Args::make_hidden(). -# "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n". -# "<input type=\"hidden\" name=\"mnt\" value=\"$Args::args{'mnt'}\">\n". -# "<input type=\"image\" src=\"pict/menu_b_rem.jpg\" ". -# "width=167 height=20 alt=\"Remove\" border=0></form>". -# "</td>\n". -# "</tr></table>\n"; - - Print::print_html_footer(); - return 0; -} - -# remove the config files -sub img_del { - Args::check_vol('vol'); - - # Args::check_ftype(); - Print::print_html_header( - "Removing Configuration Settings for $Args::args{'vol'}"); - - Caseman::del_host_config("", $Args::args{'vol'}, ""); - Caseman::update_md5($Args::args{'vol'}, ""); - - print "Settings for <tt>$Args::args{'vol'}</tt> removed from " - . "<tt>$Args::args{'case'}:$Args::args{'host'}</tt>.\n" - . "<p>NOTE: The actual file still exists in the host directory.\n"; - - print "<p><a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::VOL_OPEN&${Args::baseargs_novol}\">" - . "<img src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=\"43\" height=20 border=\"0\"></a>\n"; - - Print::print_html_footer(); - - return 0; -} - -# Make a strings -t d file for the image to decrease the search time -# Can make both ASCII and Unicode strings files -sub vol_makestr { - Print::print_html_header("Extracting Strings"); - - my $ascii = 0; - my $uni = 0; - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - if ((exists $Args::args{'str'}) && ($Args::args{'str'} == 1)) { - if (exists $Caseman::vol2str{$vol}) { - Print::print_err( -"Image already has an ASCII strings file: $Caseman::vol2sname{$vol}" - ); - } - $ascii = 1; - } - - if ((exists $Args::args{'uni'}) && ($Args::args{'uni'} == 1)) { - if (exists $Caseman::vol2uni{$vol}) { - Print::print_err( -"Image already has a Unicode strings file: $Caseman::vol2sname{$vol}" - ); - } - - $uni = 1; - } - if (($uni == 0) && ($ascii == 0)) { - goto str_egress; - } - - my $base_name = $Caseman::vol2sname{$vol}; - - if ($ascii == 1) { - my $fname_rel = "$::DATADIR/${base_name}-$ftype.asc"; - my $fname = "$::host_dir" . "$fname_rel"; - - if (-e "$fname") { - my $i = 1; - $i++ while (-e "$::host_dir" - . "$::DATADIR/" - . "${base_name}-$ftype-$i.asc"); - - $fname_rel = "$::DATADIR/${base_name}-$ftype-$i.asc"; - $fname = "$::host_dir" . "$fname_rel"; - } - - print -"Extracting ASCII strings from <tt>$Caseman::vol2sname{$vol}</tt><br>\n"; - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Saving ASCII strings to $fname_rel"); - - local *OUT; - - my $hit_cnt = 0; - $SIG{ALRM} = sub { - if (($hit_cnt++ % 5) == 0) { - print "+"; - } - else { - print "-"; - } - alarm(5); - }; - - alarm(5); - - if ($ftype eq "blkls") { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/srch_strings' -a -t d $img > '$fname'"); - } - elsif ((($ftype eq "raw") || ($ftype eq "swap")) - && ($Caseman::vol2end{$vol} != 0)) - { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " - . $Caseman::vol2start{$vol} . "-" - . $Caseman::vol2end{$vol} - . " | '$::TSKDIR/srch_strings' -a -t d > '$fname'"); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d > '$fname'" - ); - } - alarm(0); - $SIG{ALRM} = 'DEFAULT'; - - print $_ while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - - print "<br>\n" if ($hit_cnt != 0); - - # Verify that it worked - unless (open(STR, "$fname")) { - print( "Error opening $fname<br>\n" - . "Either an error occurred while generating the file or " - . "no ASCII strings exist<br>"); - goto str_uni; - } - - # append to config - my $strvol = - Caseman::add_vol_host_config("strings", "$vol $fname_rel"); - print "Host configuration file updated<br>"; - - $Caseman::vol2ftype{$strvol} = "strings"; - $Caseman::mod2vol{$strvol} = $vol; - $Caseman::vol2str{$vol} = $strvol; - $Caseman::vol2cat{$strvol} = "mod"; - $Caseman::vol2itype{$strvol} = "raw"; - - $Caseman::vol2par{$strvol} = $vol; - $Caseman::vol2path{$strvol} = "$::host_dir" . "$fname_rel"; - $Caseman::vol2start{$strvol} = 0; - $Caseman::vol2end{$strvol} = 0; - $Caseman::vol2sname{$strvol} = $fname_rel; - - # Calculate MD5 - if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { - print "Calculating MD5 Value<br><br>\n"; - my $m = Hash::int_create_wrap($strvol); - print "MD5 Value: <tt>$m</tt><br><br>\n"; - } - } - - str_uni: - - if ($uni == 1) { - - my $fname_rel = "$::DATADIR/${base_name}-$ftype.uni"; - my $fname = "$::host_dir" . "$fname_rel"; - - if (-e "$fname") { - my $i = 1; - $i++ while (-e "$::host_dir" - . "$::DATADIR/" - . "${base_name}-$ftype-$i.uni"); - - $fname_rel = "$::DATADIR/${base_name}-$ftype-$i.uni"; - $fname = "$::host_dir" . "$fname_rel"; - } - - print "<hr>\n" if ($ascii == 1); - - print -"Extracting Unicode strings from <tt>$Caseman::vol2sname{$vol}</tt><br>\n"; - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Saving Unicode strings to $fname_rel"); - - local *OUT; - - my $hit_cnt = 0; - $SIG{ALRM} = sub { - if (($hit_cnt++ % 5) == 0) { - print "+"; - } - else { - print "-"; - } - alarm(5); - }; - - alarm(5); - if ($ftype eq "blkls") { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/srch_strings' -a -t d -e l $img > '$fname'"); - } - elsif ((($ftype eq "raw") || ($ftype eq "swap")) - && ($Caseman::vol2end{$vol} != 0)) - { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " - . $Caseman::vol2start{$vol} . "-" - . $Caseman::vol2end{$vol} - . " | '$::TSKDIR/srch_strings' -a -t d -e l > '$fname'"); - } - - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -e l > '$fname'" - ); - } - - alarm(0); - $SIG{ALRM} = 'DEFAULT'; - - print $_ while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - - print "<br>\n" if ($hit_cnt != 0); - - # Verify that it worked - unless (open(STR, "$fname")) { - print "Error opening $fname<br>\n" - . "Either an error occurred while generating the file or " - . "no Unicode strings exist"; - goto str_egress; - } - - # append to config - my $strvol = - Caseman::add_vol_host_config("unistrings", "$vol $fname_rel"); - print "Host configuration file updated<br>"; - - $Caseman::vol2ftype{$strvol} = "strings"; - $Caseman::mod2vol{$strvol} = $vol; - $Caseman::vol2uni{$vol} = $strvol; - $Caseman::vol2cat{$strvol} = "mod"; - $Caseman::vol2itype{$strvol} = "raw"; - - $Caseman::vol2par{$strvol} = $vol; - $Caseman::vol2path{$strvol} = "$::host_dir" . "$fname_rel"; - $Caseman::vol2start{$strvol} = 0; - $Caseman::vol2end{$strvol} = 0; - $Caseman::vol2sname{$strvol} = $fname_rel; - - # Calculate MD5 - if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { - print "Calculating MD5 Value<br><br>\n"; - $m = Hash::int_create_wrap($strvol); - print "MD5 Value: <tt>$m</tt><br><br>\n"; - } - } - - str_egress: - - my $dest_vol = $vol; - - # We need to return with a real image to VOL_DETAILS so check the mod - $dest_vol = $Caseman::mod2vol{$vol} - if (exists $Caseman::mod2vol{$vol}); - - print "<hr><a href=\"$::PROGNAME?$Args::baseargs_novol&mod=$::MOD_CASEMAN&" - . "view=$Caseman::VOL_DETAILS&vol=$dest_vol\" target=_top>Image Details</a><p>\n"; - - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_KWSRCH&$Args::baseargs\"" - . " target=\"_top\">Keyword Search</a>\n"; - - Print::print_html_footer(); - - return 0; -} - -sub vol_makeblkls { - Print::print_html_header("Extracting Unallocated Space"); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $base_name = $Caseman::vol2sname{$vol}; - $base_name = $1 if ($base_name =~ /^(.*?)\.dd$/); - my $fname_rel = "$::DATADIR/${base_name}-$ftype.unalloc"; - my $fname = "$::host_dir" . "$fname_rel"; - - if (-e "$::host_dir" . "$fname_rel") { - my $i = 1; - $i++ while (-e "$::host_dir" - . "$::DATADIR/" - . "${base_name}-$ftype-$i.unalloc"); - - $fname_rel = "$::DATADIR/${base_name}-$ftype-$i.unalloc"; - $fname = "$::host_dir" . "$fname_rel"; - } - - Print::log_host_inv( - "$Args::args{'vol'}: Saving unallocated data to $fname_rel"); - - print -"Extracting unallocated data from <tt>$Caseman::vol2sname{$vol}</tt><br>\n"; - - local *OUT; - - my $hit_cnt = 0; - $SIG{ALRM} = sub { - if (($hit_cnt++ % 5) == 0) { - print "+"; - } - else { - print "-"; - } - alarm(5); - }; - - alarm(5); - - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkls' -f $ftype -o $offset -i $imgtype $img > '$fname'"); - - alarm(0); - $SIG{ALRM} = 'DEFAULT'; - - print "$_" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - - print "<br>\n" - if ($hit_cnt != 0); - - # append to config - my $blklsvol = Caseman::add_vol_host_config("blkls", "$vol $fname_rel"); - print "Host configuration file updated<br>"; - - $Caseman::vol2ftype{$blklsvol} = "blkls"; - $Caseman::mod2vol{$blklsvol} = $vol; - $Caseman::vol2blkls{$vol} = $blklsrvol; - $Caseman::vol2cat{$blklsvol} = "mod"; - $Caseman::vol2itype{$blklsvol} = "raw"; - - $Caseman::vol2par{$blklsvol} = $vol; - $Caseman::vol2path{$blklsvol} = "$::host_dir" . "$fname_rel"; - $Caseman::vol2start{$blklsvol} = 0; - $Caseman::vol2end{$blklsvol} = 0; - $Caseman::vol2sname{$blklsvol} = $fname_rel; - - # Calculate MD5 - if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { - print "Calculating MD5 Value<br>\n"; - my $m = Hash::int_create_wrap($blklsvol); - print "MD5 Value: <tt>$m</tt><br><br>\n"; - } - - print "<a href=\"$::PROGNAME?$Args::baseargs&mod=$::MOD_CASEMAN&" - . "view=$Caseman::VOL_DETAILS\" target=_top>Image Details</a><p>\n"; - - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_KWSRCH&$Args::baseargs_novol&" - . "vol=$fname_rel\" target=\"_top\">Keyword Search</a>\n"; - - Print::print_html_footer(); - return 0; -} - -1; diff --git a/lib/Data.pm b/lib/Data.pm deleted file mode 100644 index f8e2ef43fe..0000000000 --- a/lib/Data.pm +++ /dev/null @@ -1,927 +0,0 @@ -# -# Data / Content layer functions -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -package Data; - -$Data::FRAME = 1; -$Data::ENTER = 2; -$Data::CONT = 3; -$Data::CONT_MENU = 4; -$Data::CONT_MENU_FR = 5; -$Data::REPORT = 6; -$Data::LIST = 7; -$Data::EXPORT = 8; -$Data::BLANK = 9; - -# Display types that use the sort variable -$Data::SORT_ASC = 0; -$Data::SORT_HEX = 1; -$Data::SORT_STR = 2; - -# Types of block numbers -$Data::ADDR_DD = 0; -$Data::ADDR_BLKLS = 1; - -sub main { - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $Data::FRAME - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - # Check Basic Args - Args::check_vol('vol'); - - # These windows don't need the data unit address - if ($view == $Data::FRAME) { - return frame(); - } - elsif ($view == $Data::ENTER) { - return enter(); - } - elsif ($view == $Data::LIST) { - return list(); - } - elsif ($view == $Data::BLANK) { - return blank(); - } - - # These windows do need the data unit address - Args::check_block(); - if ($view == $Data::CONT) { - return content(); - } - elsif ($view == $Data::CONT_MENU) { - return content_menu(); - } - elsif ($view == $Data::CONT_MENU_FR) { - return content_menu_frame(); - } - elsif ($view == $Data::REPORT) { - return report(); - } - - elsif ($view == $Data::EXPORT) { - return export(); - } - else { - Print::print_check_err("Invalid Data View"); - } - -} - -# Generate the 2 frames for block browsing -sub frame { - Print::print_html_header_frameset("Data Browse on $Args::args{'vol'}"); - - print "<frameset cols=\"20%,80%\">\n"; - - # Data Contents - if (exists $Args::args{'block'}) { - my $len = Args::get_len(); - - print "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::ENTER&" - . "$Args::baseargs&block=$Args::enc_args{'block'}\">\n" - . "<frame src=\"$::PROGNAME?" - . "mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" - . "block=$Args::enc_args{'block'}&$Args::baseargs&len=$len\" " - . "name=\"content\">\n</frameset>\n"; - } - else { - print "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::ENTER&" - . "$Args::baseargs\">\n" - . "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::BLANK&" - . "$Args::baseargs\" name=\"content\">\n</frameset>\n"; - } - - Print::print_html_footer_frameset(); - return 0; -} - -# Frame to enter the data into -sub enter { - Print::print_html_header(""); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $bs = Args::get_unitsize(); - - print "<form action=\"$::PROGNAME\" method=\"get\" " - . "target=\"content\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_DATA\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Data::CONT_MENU_FR\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . Args::make_hidden() - . - - # Address - "<b>$Fs::addr_unit{$ftype} Number:</b><br>    " - . "<input type=\"text\" name=\"block\" size=12 maxlength=12"; - print " value=\"$Args::enc_args{'block'}\"" - if (exists $Args::args{'block'}); - print ">\n"; - - # Number of units - print "<p><b>Number of $Fs::addr_unit{$ftype}" . "s:</b>" - . "<br>    " - . "<input type=\"text\" name=\"len\" value=\"1\" size=6 maxlength=6>\n"; - - print "<p><b>$Fs::addr_unit{$ftype} Size:</b>" . " $bs\n"; - - # blkls images do not get to select this - # if (($ftype ne 'blkls') && ($ftype ne 'swap') && ($ftype ne 'raw')) { - if ($Fs::is_fs{$ftype} == 1) { - print "<p><b>Address Type:</b><br>    " - . "<select name=\"btype\" size=1>\n" - . "<option value=\"$Data::ADDR_DD\" selected>Regular (dd)</option>\n" - . "<option value=\"$Data::ADDR_BLKLS\">Unallocated (blkls)</option>\n" - . "</select>\n"; - } - else { - print - "<input type=\"hidden\" name=\"btype\" value=\"$Data::ADDR_DD\">\n"; - } - - # Lazarus - print "<p><b>Lazarus Addr:</b> " - . "<input type=\"checkbox\" name=\"btype2\">\n" - . "<p><input type=\"image\" src=\"pict/but_view.jpg\" " - . "width=45 height=22 alt=\"View\" border=\"0\">\n" - . "</form>\n"; - - print "<hr><p>" - . "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&$Args::baseargs\" target=\"content\">" - . "<img src=\"pict/but_alloc_list.jpg\" border=\"0\" " - . "width=113 height=20 alt=\"Allocation List\"></a><br>\n" - if ($Fs::is_fs{$ftype} == 1); - - # unless (($ftype eq 'blkls') || ($ftype eq 'swap') || ($ftype eq 'raw')); - - # If there is a blkls image, then provide a button for it - if (($ftype ne 'blkls') && (exists $Caseman::vol2blkls{$vol})) { - print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" - . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_DATA\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$Caseman::vol2blkls{$vol}\">\n" - . Args::make_hidden() - . "<p><input type=\"image\" src=\"pict/srch_b_lun.jpg\" " - . "alt=\"Load Unallocated Image\" border=\"0\">\n<br></form>\n"; - } - - # If we are using a blkls image, then give a button for the original - elsif (($ftype eq 'blkls') && (exists $Caseman::mod2vol{$vol})) { - print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" - . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_DATA\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$Caseman::mod2vol{$vol}\">\n" - . Args::make_hidden() - . "<p><input type=\"image\" src=\"pict/srch_b_lorig.jpg\" " - . "alt=\"Load Original Image\" border=\"0\">\n<br></form>\n"; - } - - Print::print_html_footer(); - return 0; -} - -# generate frame for block content -sub content_menu_frame { - Print::print_html_header_frameset(""); - - my $sort = $Data::SORT_ASC; - $sort = $1 - if ((exists $Args::args{'sort'}) && ($Args::args{'sort'} =~ /^(\d+)$/)); - - my $len = Args::get_len(); - if ($len == 0) { - Print::print_err("Invalid length: 0"); - } - - my $blk; - - my $ifind = Args::get_ifind(); - - # off is 1 if a lazarus block number as they are off by one - my $off = 0; - $off = -1 if (exists $Args::args{'btype2'}); - - # Do we need to convert from blkls value to dd value ? - if ( (exists $Args::args{'btype'}) - && ($Args::args{'btype'} == $Data::ADDR_BLKLS)) - { - - my $vol = Args::get_vol('vol'); - my $b = Args::get_block() + $off; - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkcalc' -f $ftype -u $b -o $offset -i $imgtype $img"); - $blk = Exec::read_pipe_line(*OUT); - close(OUT); - - $blk = "Error getting block" - if ((!defined $blk) || ($blk eq "")); - - if ($blk !~ /^\d+$/) { - print "$blk\n"; - return 1; - } - } - else { - $blk = Args::get_block() + $off; - } - - print "<frameset rows=\"25%,75%\">\n" - . "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU&$Args::baseargs" - . "&block=$blk&sort=$sort&len=$len&ifind=$ifind\">\n" - . "<frame src=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT&$Args::baseargs" - . "&block=$blk&sort=$sort&len=$len\" name=\"cont2\">\n" - . "</frameset>"; - - Print::print_html_footer_frameset(); - return 0; -} - -sub print_ifind { - my $block = Args::get_block(); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Finding $Fs::meta_str{$ftype} for data unit $block" - ); - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ifind' -f $ftype -d $block -o $offset -i $imgtype $img"); - my $meta = Exec::read_pipe_line(*OUT); - close(OUT); - - $meta = "Error getting meta address" - if ((!defined $meta) || ($meta eq "")); - - if ($meta =~ /^($::REG_META)$/o) { - $meta = $1; - my $tmpr = $Caseman::vol2mnt{$vol}; - print "<b>Pointed to by $Fs::meta_str{$ftype}:</b> " - . "<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&" - . "meta=$meta\" target=\"_top\">$meta</a><br>\n"; - - print "<b>Pointed to by file:</b>\n"; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - - # Make it red if it is deleted - if (/^(\*)\s+\/*(.*)$/) { - Print::print_output("<tt><font color=\"$::DEL_COLOR[0]\">" - . Print::html_encode(${tmpr} . ${2}) - . "</font></tt> (deleted)<br>\n"); - } - - # If it starts with a '/' then it must be a file - elsif (/^\/(.*)$/) { - Print::print_output("<tt>" - . Print::html_encode(${tmpr} . ${1}) - . "</tt><br>\n"); - } - - # this must be an error - else { - Print::print_output(Print::html_encode($_) . "<br>\n"); - } - } - close(OUT); - } - else { - print "$meta\n"; - } -} - -# Generate index for block content -sub content_menu { - Print::print_html_header(""); - - my $block = Args::get_block(); - my $prev = $block - 1; - my $next = $block + 1; - - my $sort = Args::get_sort(); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $ifind = Args::get_ifind(); - - my $len = Args::get_len(); - my $bs = Args::get_unitsize(); - - if ($len == 0) { - Print::print_err("Invalid length: 0"); - } - - print "<center>"; - my $url = - "$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" - . "$Args::baseargs&sort=$sort&len=$len" - . "&ifind=$ifind"; - - # Next and Previous pointers - print "<table cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr>\n"; - - # Previous - if ($prev < $Fs::first_addr{$ftype}) { - print "<td align=\"right\"> </td>\n"; - } - else { - print "<td align=\"right\">" - . "<a href=\"$url&block=$prev\" target=\"_parent\">\n" - . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " - . "width=\"89\" height=20 border=\"0\"></a></td>\n"; - } - - # Next - print "<td align=\"left\"><a href=\"$url&block=$next\"" - . " target=\"_parent\">" - . "<img src=\"pict/but_next.jpg\" alt=\"next\" " - . "width=\"89\" height=20 border=\"0\"></a></td>\n</tr>\n"; - - print "<tr><td align=\"right\"><a href=\"$::PROGNAME?" - . "mod=$::MOD_DATA&view=$Data::EXPORT&$Args::baseargs&" - . "block=$block&len=$len\">" - . "<img src=\"pict/but_export.jpg\" border=\"0\" alt=\"Export\" " - . "width=123 height=20></a></td>\n"; - - if ($::USE_NOTES == 1) { - print "<td align=\"left\">" - . "<a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::ENTER_DATA&$Args::baseargs&block=$block&len=$len\" " - . "target=\"_blank\">" - . "<img src=\"pict/but_addnote.jpg\" border=\"0\" " - . "width=\"89\" height=20 alt=\"Add Note\"></a></td>\n"; - } - else { - print "<td align=\"left\"> </td>\n"; - } - - print "</tr></table>\n"; - - # Display formats - print "<table cellspacing=\"0\" cellpadding=\"2\">\n" . "<tr><td>ASCII ("; - if ($sort == $Data::SORT_ASC) { - print "display - "; - } - else { - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" - . "$Args::baseargs&" - . "sort=$Data::SORT_ASC&block=$block&len=$len\" target=\"_parent\">" - . "display</a> - \n"; - } - - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::REPORT&" - . "$Args::baseargs&sort=$Data::SORT_ASC" - . "&block=$block&len=$len\" target=\"_blank\">report</a>)</td>\n" - . "<td>*</td>\n"; - - print "<td>Hex ("; - if ($sort == $Data::SORT_HEX) { - print "display - "; - } - else { - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" - . "$Args::baseargs&" - . "sort=$Data::SORT_HEX&block=$block&len=$len\" target=\"_parent\">" - . "display</a> - \n"; - } - - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::REPORT&" - . "$Args::baseargs&sort=$Data::SORT_HEX" - . "&block=$block&len=$len\" target=\"_blank\">report</a>)</td>\n" - . "<td>*</td>\n"; - - print "<td>ASCII Strings ("; - if ($sort == $Data::SORT_STR) { - print "display - "; - } - else { - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" - . "$Args::baseargs&" - . "sort=$Data::SORT_STR&block=$block&len=$len\" target=\"_parent\">" - . "display</a> - \n"; - } - - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::REPORT&" - . "$Args::baseargs&sort=$Data::SORT_STR" - . "&block=$block&len=$len\" target=\"_blank\">report</a>)</td>\n" - . "</tr></table>\n"; - - # Special case for 'blkls' b.c. we need to specify original data unit size - local *OUT; - if ($ftype eq 'blkls') { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype -u $bs -o $offset -i $imgtype $img $block | '$::FILE_EXE' -z -b -" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype -o $offset -i $imgtype $img $block | '$::FILE_EXE' -z -b -" - ); - } - my $file_type = Exec::read_pipe_line(*OUT); - close(OUT); - - $file_type = "Error getting file type" - if ((!defined $file_type) || ($file_type eq "")); - - print "<b>File Type:</b> $file_type<br></center>\n"; - - if ($len == 1) { - print "<b>$Fs::addr_unit{$ftype}:</b> $block<br>\n"; - } - else { - my $end = $block + $len - 1; - print "<b>$Fs::addr_unit{$ftype}" . "s:</b> $block-$end<br>\n"; - } - if ($Fs::is_fs{$ftype} == 1) { - - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkstat' -f $ftype -o $offset -i $imgtype $img $block" - ); - - my $cnt = 0; - while ($_ = Exec::read_pipe_line(*OUT)) { - - if ($_ =~ /((Not )?Allocated)/) { - print "<font color=\"$::DEL_COLOR[0]\">" if (defined $2); - print "<b>Status:</b> $1<br>"; - print "</font>" if (defined $2); - } - elsif ($_ =~ /Group: (\d+)/) { - print "<b>Group:</b> $1<br>\n"; - } - $cnt++; - } - close(OUT); - if ($cnt == 0) { - print "Invalid $Fs::addr_unit{$ftype} address<br>\n"; - return; - } - - # Make ifind an option - $url = - "$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU&" - . "$Args::baseargs&sort=$sort&len=$len&block=$block"; - if ($ifind == 0) { - print "<a href=\"$url&ifind=1\">Find Meta Data Address</a><br>\n"; - } - else { - print "<a href=\"$url&ifind=0\">Hide Meta Data Address</a><br>\n"; - print_ifind(); - } - } - - # Option to view original if it exists - if ( ($ftype eq 'blkls') - && (exists $Caseman::mod2vol{$vol})) - { - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&" - . "view=$Data::CONT_MENU_FR&${Args::baseargs_novol}" - . "&vol=$Caseman::mod2vol{$vol}&" - . "block=$block&sort=$sort&len=$len&btype=$Data::ADDR_BLKLS\" " - . "target=\"_parent\">View Original</a><br>\n"; - } - - Print::print_html_footer(); - return 0; -} - -#Display actual block content -sub content { - Args::check_sort(); - - Print::print_text_header(); - - my $sort = Args::get_sort(); - my $block = Args::get_block(); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $len = Args::get_len(); - my $bs = Args::get_unitsize(); - - my $range = ""; - if ($len == 0) { - print "Invalid length: 0\n"; - exit(1); - } - elsif ($len == 1) { - $range = "$Fs::addr_unit{$ftype} $block"; - } - else { - my $end = $block + $len - 1; - $range = "$Fs::addr_unit{$ftype}" . "s $block-$end"; - } - my $str = "Contents of $range in $Caseman::vol2sname{$vol}\n\n\n"; - my $log_str = "contents of $range"; - - my $usize_str = ""; - $usize_str = " -u $bs " - if ($ftype eq 'blkls'); - - local *OUT; - if ($sort == $Data::SORT_HEX) { - print "Hex " . $str; - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Displaying Hex $log_str"); - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -h -o $offset -i $imgtype $img $block $len" - ); - } - elsif ($sort == $Data::SORT_ASC) { - print "ASCII " . $str; - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Displaying ASCII $log_str"); - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -a -o $offset -i $imgtype $img $block $len" - ); - } - elsif ($sort == $Data::SORT_STR) { - print "ASCII String " . $str; - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Displaying string $log_str"); - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::TSKDIR/srch_strings' -a" - ); - } - print $_ while ($_ = Exec::read_pipe_data(*OUT, 512)); - close(OUT); - - Print::print_text_footer(); - - return 0; -} - -sub report { - Args::check_sort(); - - my $sort = Args::get_sort(); - my $vol = Args::get_vol('vol'); - my $block = Args::get_block(); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $len = Args::get_len(); - my $type; - - if ($len == 0) { - print("Invalid length: 0"); - exit(1); - } - my $bs = Args::get_unitsize(); - - my $usize_str = ""; - $usize_str = " -u $bs " if ($ftype eq 'blkls'); - - Print::print_text_header("$vol" . "-" - . "$Fs::addr_unit{$ftype}" - . "$Args::args{'block'}" - . ".txt"); - - if ($sort == $Data::SORT_ASC) { - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Generating ASCII report on data unit $block" - ); - $type = "ascii"; - } - elsif ($sort == $Data::SORT_STR) { - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Generating ASCII strings report on data unit $block" - ); - $type = "string"; - } - elsif ($sort == $Data::SORT_HEX) { - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Generating hex report on data unit $block" - ); - $type = "hex"; - } - else { - print "\n\n"; - print "invalid sort value"; - return 1; - } - - print " Autopsy $type $Fs::addr_unit{$ftype} Report\n\n" - . "-" x 70 . "\n" - . " GENERAL INFORMATION\n\n"; - - if ($len == 1) { - print "$Fs::addr_unit{$ftype}: $Args::args{'block'}\n"; - } - else { - my $end = $block + $len - 1; - print "$Fs::addr_unit{$ftype}" . "s: $Args::args{'block'}-$end\n"; - } - print "$Fs::addr_unit{$ftype} Size: $bs\n"; - - # if (($ftype ne 'blkls') && ($ftype ne 'raw') && ($ftype ne 'swap')) { - if ($Fs::is_fs{$ftype} == 1) { - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ifind' -f $ftype -d $block -o $offset -i $imgtype $img" - ); - my $meta = Exec::read_pipe_line(*OUT); - close(OUT); - - $meta = "Error getting meta address" - if ((!defined $meta) || ($meta eq "")); - - if ($meta =~ /^($::REG_META)$/o) { - my $tmpi = $1; - print "\nPointed to by $Fs::meta_str{$ftype}: $tmpi\n"; - - my $tmpr = $Caseman::vol2mnt{$vol}; - print "Pointed to by files:\n"; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $tmpi" - ); - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - if (/^(\*)\s+\/*(.*)$/) { - Print::print_output( - " $tmpr$2 (deleted)\n"); - } - elsif (/^\/(.*)$/) { - Print::print_output( - " $tmpr$1\n"); - } - else { - Print::print_output(" $_\n"); - } - } - close(OUT); - } - else { - print "Not allocated to any meta data structures\n"; - } - } # not blkls - - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::MD5_EXE'" - ); - my $md5 = Exec::read_pipe_line(*OUT); - close(OUT); - - $md5 = "Error getting md5" - if ((!defined $md5) || ($md5 eq "")); - - chop $md5; - print "MD5 of raw $Fs::addr_unit{$ftype}: $md5\n"; - - if ($sort == $Data::SORT_HEX) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -h -o $offset -i $imgtype $img $block $len | '$::MD5_EXE'" - ); - } - elsif ($sort == $Data::SORT_ASC) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -a -o $offset -i $imgtype $img $block $len | '$::MD5_EXE'" - ); - } - elsif ($sort == $Data::SORT_STR) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::TSKDIR/srch_strings' -a | '$::MD5_EXE'" - ); - } - - $md5 = Exec::read_pipe_line(*OUT); - close(OUT); - - $md5 = "Error getting md5" - if ((!defined $md5) || ($md5 eq "")); - - chop $md5; - print "MD5 of $type output: $md5\n"; - - print "\nImage: $Caseman::vol2path{$vol}\n"; - if (($Caseman::vol2start{$vol} == 0) && ($Caseman::vol2end{$vol} == 0)) { - print "Offset: Full image\n"; - } - elsif ($Caseman::vol2end{$vol} == 0) { - print "Offset: $Caseman::vol2start{$vol} to end\n"; - } - else { - print "Offset: $Caseman::vol2start{$vol} to $Caseman::vol2end{$vol}\n"; - } - print "File System Type: $ftype\n"; - - my $date = localtime(); - - print "\nDate Generated: $date\n" - . "Investigator: $Args::args{'inv'}\n" - . "-" x 70 . "\n" - . " CONTENT\n\n"; - - if ($sort == $Data::SORT_HEX) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -h -o $offset -i $imgtype $img $block $len" - ); - } - elsif ($sort == $Data::SORT_ASC) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -a -o $offset -i $imgtype $img $block $len" - ); - } - elsif ($sort == $Data::SORT_STR) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype $usize_str -o $offset -i $imgtype $img $block $len | '$::TSKDIR/srch_strings' -a" - ); - } - Print::print_output($_) - while ($_ = Exec::read_pipe_data(*OUT, 512)); - close(OUT); - - print "\n" - . "-" x 70 . "\n" - . " VERSION INFORMATION\n\n" - . "Autopsy Version: $::VER\n"; - print "The Sleuth Kit Version: " . ::get_tskver() . "\n"; - - Print::print_text_footer(); - - return 0; -} - -# -# Display the block allocation list -# -sub list { - Print::print_html_header("Block Allocation List"); - - my $BLKLS_GAP = 500; - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $min = 0; - $min = Args::get_min() if (exists $Args::args{'min'}); - my $max = $min + $BLKLS_GAP - 1; - - # set fmin to the minimum for the file system - my $fmin = $min; - $fmin = $Fs::first_addr{$ftype} if ($min < $Fs::first_addr{$ftype}); - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Block Allocation List for $min to $max"); - print "<center><H2>$Fs::addr_unit{$ftype}: $min - $max</H2>"; - - my $tmp; - - if ($min - $BLKLS_GAP >= 0) { - $tmp = $min - $BLKLS_GAP; - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" - . "$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " - . "width=\"89\" height=20 border=\"0\"></a> "; - } - $tmp = $min + $BLKLS_GAP; - print " <a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" - . "$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_next.jpg\" alt=\"next\" " - . "width=\"89\" height=20 border=\"0\"></a><br>"; - print "</center>\n"; - - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkls' -el -f $ftype -o $offset -i $imgtype $img $fmin-$max" - ); - while ($_ = Exec::read_pipe_line(*OUT)) { - if (/^(\d+)\|([af])/) { - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&" - . "view=$Data::CONT_MENU_FR&$Args::baseargs&block=$1\">" - . "$1:</a> "; - if ($2 eq "a") { - print "allocated<br>\n"; - } - else { - print "<font color=\"$::DEL_COLOR[0]\">free</font><br>\n"; - } - } - } - close(OUT); - - print "<center>\n"; - if ($min - $BLKLS_GAP >= 0) { - $tmp = $min - $BLKLS_GAP; - print "<a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" - . "$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " - . "width=\"89\" height=20 border=\"0\"></a> "; - } - $tmp = $min + $BLKLS_GAP; - print " <a href=\"$::PROGNAME?mod=$::MOD_DATA&view=$Data::LIST&" - . "$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_next.jpg\" alt=\"next\" " - . "width=\"89\" height=20 border=\"0\"></a><br>"; - print "</center>\n"; - - Print::print_html_footer(); - return 0; -} - -sub export { - my $block = Args::get_block(); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $len = Args::get_len(); - my $bs = Args::get_unitsize(); - - Print::print_oct_header( - "$vol" . "-" . "$Fs::addr_unit{$ftype}" . "$block" . ".raw"); - - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Saving contents of data unit $block (unit size: $bs number: $len)" - ); - - local *OUT; - if ($ftype eq 'blkls') { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype -u $bs -o $offset -i $imgtype $img $block $len" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkcat' -f $ftype -o $offset -i $imgtype $img $block $len" - ); - } - print "$_" while ($_ = Exec::read_pipe_data(*OUT, 512)); - close(OUT); - - Print::print_oct_footer(); - return 0; -} - -# Blank Page -sub blank { - Print::print_html_header("Data Unit Blank Page"); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - - print "<center><h3>Data Unit Mode</h3><br>\n" - . "Here you can view the contents of any $Fs::addr_unit{$ftype} in the file system.<br>\n" - . "Enter the address in the field on the left.\n"; - Print::print_html_footer(); - return 0; -} diff --git a/lib/Exec.pm b/lib/Exec.pm deleted file mode 100644 index e138712756..0000000000 --- a/lib/Exec.pm +++ /dev/null @@ -1,91 +0,0 @@ -# -# Functions that wrap the execution of tools so that they are logged -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -package Exec; - -# exec_pipe(HANDLE, CMD); -sub exec_pipe { - my $handle = shift(@_); - my $cmd = shift(@_); - - die "Can't open pipe for exec_pipe" - unless defined(my $pid = open($handle, '-|')); - - if ($pid) { - return $handle; - } - else { - $| = 1; - Print::log_host_inv_exec("$cmd"); - exec("$cmd") or die "Can't exec program: $!"; - } -} - -sub read_pipe_line { - my $handle = shift(@_); - my $out; - -# for (my $i = 0; ($len = read ($handle, $$buf, $size)) && (!defined $len); $i++) { - - for (my $i = 0; $i < 100; $i++) { - $out = <$handle>; - return $out if (defined $out); - } - return $out; -} - -sub read_pipe_data { - my $handle = shift(@_); - my $size = shift(@_); - my $out; - my $len; - - for ( - my $i = 0; - ($len = read($handle, $out, $size)) && (!defined $len) && ($i < 100); - $i++ - ) - { - } - - return $out; -} - -sub exec_sys { - my $cmd = shift(@_); - Print::log_host_inv_exec("$cmd"); - system($cmd); - return; -} - -1; diff --git a/lib/File.pm b/lib/File.pm deleted file mode 100644 index 59696d013c..0000000000 --- a/lib/File.pm +++ /dev/null @@ -1,2310 +0,0 @@ -# -# File name layer functions -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -# Updated 1/15 - -package File; - -# If the order of these views are changed, then the checks in main -# must be as well -$File::BLANK = 0; -$File::FRAME = 1; -$File::DIR_LIST = 2; -$File::FILE_LIST_DIR = 3; -$File::FILE_LIST_FILE = 4; -$File::FILE_LIST_DEL = 5; -$File::FILE_LIST = 6; -$File::CONT = 7; -$File::CONT_FR = 8; -$File::CONT_MENU = 9; -$File::REPORT = 10; -$File::EXPORT = 11; -$File::MD5LIST = 12; -$File::CONT_IMG = 13; - -$File::REC_NO = 0; -$File::REC_YES = 1; - -sub main { - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $File::FRAME - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - if ($view == $File::BLANK) { - blank(); - return 0; - } - - # Check Basic Args - Args::check_vol('vol'); - - # These windows don't need the meta data address - if ($view < $File::FILE_LIST) { - - if ($view == $File::FRAME) { - return frame(); - } - - Args::check_dir(); - if ($view == $File::DIR_LIST) { - return dir_list(); - } - elsif ($view == $File::FILE_LIST_DIR) { - return file_list_dir(); - } - elsif ($view == $File::FILE_LIST_DEL) { - return file_list_del(); - } - elsif ($view == $File::FILE_LIST_FILE) { - return file_list_file(); - } - } - - # These windows need the meta data address - Args::check_dir(); - Args::check_meta('meta'); - - if ($view < $File::REPORT) { - if ($view == $File::FILE_LIST) { - return file_list(); - } - elsif ($view == $File::CONT) { - return content(); - } - elsif ($view == $File::CONT_FR) { - return content_fr(); - } - elsif ($view == $File::CONT_MENU) { - return content_menu(); - } - } - else { - if ($view == $File::REPORT) { - return report(); - } - elsif ($view == $File::EXPORT) { - return export(); - } - elsif ($view == $File::MD5LIST) { - return md5list(); - } - elsif ($view == $File::CONT_IMG) { - return content_img(); - } - } - - Print::print_check_err("Invalid File View"); -} - -# Sorting and display types -my $FIL_SORT_ASC = 0; -my $FIL_SORT_STR = 1; -my $FIL_SORT_HEX = 2; - -# Methods of sorting the file listings -my $SORT_DTYPE = 0; # type according to dentry -my $SORT_ITYPE = 1; # type according to meta -my $SORT_NAME = 2; -my $SORT_MOD = 3; -my $SORT_ACC = 4; -my $SORT_CHG = 5; -my $SORT_CRT = 6; -my $SORT_SIZE = 7; -my $SORT_GID = 8; -my $SORT_UID = 9; -my $SORT_META = 10; -my $SORT_DEL = 11; - -my $DIRMODE_SHOW = 1; -my $DIRMODE_NOSHOW = 2; - -# -# Make the three frames and fill them in -# -sub frame { - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $ftype = $Caseman::vol2ftype{$vol}; - - # If we were not given the meta, then look up the root - unless (exists $Args::args{'meta'}) { - $Args::args{'meta'} = $Args::enc_args{'meta'} = $Fs::root_meta{$ftype}; - } - - unless (exists $Args::args{'dir'}) { - $Args::enc_args{'dir'} = $Args::args{'dir'} = "/"; - } - - Args::check_meta('meta'); - Args::check_dir(); - - my $meta = Args::get_meta('meta'); - my $dir = Args::get_dir(); - - Print::print_html_header_frameset("$mnt$dir on $Args::args{'vol'}"); - - my $sort = $SORT_NAME; - $sort = $Args::args{'sort'} if (exists $Args::args{'sort'}); - - my $dirmode = $DIRMODE_NOSHOW; - $dirmode = $Args::args{'dirmode'} if (exists $Args::args{'dirmode'}); - - print "<frameset cols=\"175,*\">\n"; - - # Directory Listing on Left - my $url = - "$::PROGNAME?$Args::baseargs&dir=$dir&" . "sort=$sort&dirmode=$dirmode"; - - print "<frame src=\"$url&mod=$::MOD_FILE&view=$File::DIR_LIST\">\n"; - - # File frameset on right - print "<frameset rows=\"50%,50%\">\n"; - - # File Listings on top - print - "<frame src=\"$url&mod=$::MOD_FILE&view=$File::FILE_LIST&meta=$meta\" " - . "name=\"list\">\n"; - - # File Contents - print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::BLANK&" - . "$Args::baseargs\" name=\"content\">\n" - . "</frameset>\n" - . "</frameset>\n"; - - Print::print_html_footer_frameset(); - return 0; -} - -# -# Print the directory names for the lhs frame and other -# Search forms -# - -sub dir_list { - Args::check_sort(); - Args::check_dirmode(); - - Print::print_html_header(""); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $sort = Args::get_sort(); - my $dirmode = Args::get_dirmode(); - my $mnt = $Caseman::vol2mnt{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $lcldir = ""; - my $prev_plus = ""; # previous number of '+' directory spacers - my $prev_fname = ""; - my $prev_meta = ""; - - # Field to enter a directory into: - print "<p><form action=\"$::PROGNAME\" method=\"get\" target=\"list\">\n" - . "<center><b>Directory Seek</b></center><br>" - . "Enter the name of a directory that you want to view.<br>" - . "<tt>$mnt</tt>" - . "<input type=\"text\" name=\"dir\" size=24 maxlength=100>\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FILE\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$File::FILE_LIST_DIR\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . "<input type=\"hidden\" name=\"sort\" value=\"$Args::args{'sort'}\">\n" - . "<input type=\"hidden\" name=\"dirmode\" value=\"$Args::args{'dirmode'}\">\n" - . Args::make_hidden() - . - - # View Button - "<br><input type=\"image\" src=\"pict/but_view.jpg\" " - . "width=45 height=22 alt=\"View\" border=\"0\"></form>\n"; - - # Field to enter a name into: - print - "<hr><p><form action=\"$::PROGNAME\" method=\"get\" target=\"list\">\n" - . "<center><b>File Name Search</b></center><br>" - . "Enter a Perl regular expression for the file names you want to find.<br><br>\n" - . "<input type=\"text\" name=\"dir\" size=24 maxlength=100>\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FILE\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$File::FILE_LIST_FILE\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n" - . "<input type=\"hidden\" name=\"sort\" value=\"$Args::args{'sort'}\">\n" - . "<input type=\"hidden\" name=\"dirmode\" value=\"$Args::args{'dirmode'}\">\n" - . Args::make_hidden() - . "<br>\n" - . - - # Search Button - "<input type=\"image\" src=\"pict/but_search.jpg\" " - . "width=61 height=22 alt=\"Search\" border=\"0\"></form>\n"; - - print "<p><hr><p>\n"; - - my $base_url = "$::PROGNAME?$Args::baseargs&sort=$sort"; - - # All deleted files button - print "<a href=\"$base_url&mod=$::MOD_FILE&view=$File::FILE_LIST_DEL&" - . "dir=&dirmode=$dirmode\" target=\"list\">" - . "<img border=\"0\" src=\"pict/file_b_alldel.jpg\" width=\"127\" " - . "alt=\"Show All Deleted Files\">" - . "</a><p>\n"; - - # The dirmode arg shows if we should expand the whole directory listing - # or not - if ($dirmode == $DIRMODE_NOSHOW) { - print "<a href=\"$base_url&mod=$::MOD_FILE&view=$File::FRAME&" - . "dirmode=$DIRMODE_SHOW\" target=\"_parent\">" - . "<img src=\"pict/file_b_expand.jpg\" alt=\"Expand All Directories\" " - . "border=\"0\"></a><p><hr>\n"; - - return; - } - else { - print "<a href=\"$base_url&mod=$::MOD_FILE&view=$File::FRAME&" - . "dirmode=$DIRMODE_NOSHOW\" target=\"_parent\">" - . "<img src=\"pict/file_b_hide.jpg\" alt=\"Hide All Directories\" " - . "border=\"0\"></a><p><hr>\n"; - } - - $base_url .= "&dirmode=$dirmode"; - - Print::log_host_inv("$Args::args{'vol'}: List of all directories"); - - # We need to maintain state to create dir and this is done by - # counting the + marks. - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/fls' -f $ftype -ruD -o $offset -i $imgtype $img"); - - # Print root - my $url = - "$base_url&mod=$::MOD_FILE&view=$File::FILE_LIST&" - . "meta=$Fs::root_meta{$ftype}&dir="; - print "<p><a href=\"$url\" target=\"list\">$mnt</a><br>\n"; - - while ($_ = Exec::read_pipe_line(*OUT)) { - if ( -/^(\*)?(\+*)\s*[\-d]\/[\-d]\s*(\d+)\-?\d*\-?\d*\s*(\(realloc\))?:\t(.+)$/ - ) - { - - my $del = $1; - my $plus = $2; - my $meta = $3; - my $re = $4; - my $fname = $5; - - # Adjust the dir value using the '++' values to determine - # how "deep" we are - unless ($prev_plus eq $plus) { - - # are we in 1 more - if ($plus eq $prev_plus . '+') { - $lcldir .= ($prev_fname . "/"); - } - - # we are back (at least one) - elsif (defined $plus) { - my @dirs = split('/', $lcldir); - my $idx = -1; - $lcldir = ""; - - while (($idx = index($plus, '+', $idx + 1)) != -1) { - $lcldir .= ($dirs[$idx] . "/"); - } - } - } - - $prev_plus = $plus; - $prev_fname = $fname; - $prev_meta = $meta; - - $url = - "$base_url&mod=$::MOD_FILE&view=$File::FILE_LIST&" - . "meta=$meta&dir=" - . Args::url_encode($lcldir . $fname . "/"); - - print "<font color=\"$::DEL_COLOR[0]\">" if defined $del; - print "+$plus<a href=\"$url\" target=\"list\"><tt>/" - . Print::html_encode($fname) - . "</tt></a><br>\n"; - print "</font>" if defined $del; - } - } - close(OUT); - Print::print_html_footer(); - return 0; - -}; # end of FIL_DIR - -# Print the files and directories for the upper rhs frame -# These can be sorted in any format -# -# We need to find a way to cache this data -# -sub file_list { - Args::check_sort(); - Args::check_dirmode(); - - my $vol = Args::get_vol('vol'); - my $sort = Args::get_sort(); - my $ftype = $Caseman::vol2ftype{$vol}; - my $meta = Args::get_meta('meta'); - my $mnt = $Caseman::vol2mnt{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $fname = "$mnt$Args::args{'dir'}"; - $fname =~ s/\/\//\//g; - - my $sp = "  "; - - Print::print_html_header("Entries in $fname"); - - my (@itype, @dtype, @name, @mod, @acc, @chg, @crt, @size, @gid, @uid, - @meta); - my (@dir, @entry, @del, @realloc, @meta_int); - - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Directory listing of $fname ($meta)"); - - local *OUT; - - # execute command - Exec::exec_pipe(*OUT, -"'$::TSKDIR/fls' -f $ftype -la $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" - ); - - # Make the big table, small table, and start the current directory - - my $iurl = -"$::PROGNAME?$Args::baseargs&dirmode=$Args::enc_args{'dirmode'}&sort=$sort"; - - # base number of columns in table - my $cols = 15; - $cols += 2 if ($Fs::has_ctime{$ftype}); - $cols += 2 if ($Fs::has_crtime{$ftype}); - $cols += 2 if ($Fs::has_mtime{$ftype}); - - print <<EOF1; -<!-- Big Table --> -<table cellspacing=\"0\" cellpadding=\"2\" border=0> - -<!-- Small Table --> -<tr> - <td colspan=$cols> - <table border=0 align=\"left\" cellspacing=\"0\" cellpadding=\"2\" width=500> - <tr> - <td colspan=2><b>Current Directory:</b> <tt> - - <a href=\"${iurl}&mod=$::MOD_FILE&view=$File::FILE_LIST&meta=$Fs::root_meta{$ftype}&dir=\">$mnt</a>  - -EOF1 - - # Each file in the path will get its own link - $iurl .= "&mod=$::MOD_FILE&view=$File::FILE_LIST_DIR"; - my $path = ""; - my @dir_split = split('/', $Args::args{'dir'}); - while (scalar @dir_split > 1) { - my $d = shift @dir_split; - - next if ($d eq ''); - - $path .= "$d/"; - print " <a href=\"${iurl}&dir=$path\">/${d}/</a> \n"; - } - print " /$dir_split[0]/ \n" - if (scalar @dir_split == 1); - - print " </tt></td>\n" . " </tr>\n"; - - # Add Note Button - $iurl = -"&$Args::baseargs&dir=$Args::enc_args{'dir'}&meta=$Args::enc_args{'meta'}"; - if ($::USE_NOTES == 1) { - - print <<EOF2; - <tr> - <td width=\"100\" align=left> - <a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::ENTER_FILE$iurl\" target=\"_blank\"> - <img border=\"0\" src=\"pict/but_addnote.jpg\" width=\"89\" height=20 alt=\"Add Note About Directory\"> - </a> - </td> -EOF2 - - } - - # Generate MD5 List Button - print <<EOF3; - - <td width=\"206\" align=left> - <a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::MD5LIST$iurl\" target=\"_blank\"> - <img border=\"0\" src=\"pict/file_b_md5list.jpg\" width=\"206\" alt=\"Generate list of MD5 values\"> - </a> - </td> - </tr> - <!-- END of Little Table --> - </table> - </td> -</tr> -<tr> - <td colspan=$cols><hr></td> -</tr> - -EOF3 - - # Make the Table and Headers - my $url = - "$::PROGNAME?mod=$::MOD_FILE&view=$File::FRAME&" - . "$Args::baseargs&meta=$Args::enc_args{'meta'}" - . "&dir=$Args::enc_args{'dir'}&dirmode=$Args::enc_args{'dirmode'}"; - - print "<tr valign=\"MIDDLE\" " . "background=\"$::YEL_PIX\">\n"; - - # Print the Headers - If the sorting mode is set to it, then don't - # make it a link and print a different button - if ($sort == $SORT_DEL) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_del_cur.jpg\" " - . "width=\"49\" height=20 " - . "alt=\"Deleted Files\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_DEL"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_del_link.jpg\" " - . "width=\"28\" height=20 " - . "alt=\"Deleted Files\">" - . "</a></td>\n"; - } - - # type only gets one column for two 'types' - print " <td background=\"$::YEL_PIX\">$sp</td>\n" - . " <th align=\"center\" background=\"$::YEL_PIX\">" - . "  Type  <br>"; - - if ($sort == $SORT_DTYPE) { - print "dir"; - } - else { - $iurl = $url . "&sort=$SORT_DTYPE"; - print "<a href=\"$iurl\" target=\"_parent\">dir</a>"; - } - - print " / "; - - if ($sort == $SORT_ITYPE) { - print "in</th>\n"; - } - else { - $iurl = $url . "&sort=$SORT_ITYPE"; - print "<a href=\"$iurl\" target=\"_parent\">in</a></th>\n"; - } - - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - - if ($sort == $SORT_NAME) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_nam_cur.jpg\" " - . "width=\"76\" height=20 " - . "alt=\"File Name\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_NAME"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_nam_link.jpg\" " - . "width=\"50\" height=20 " - . "alt=\"File Name\">" - . "</a></td>\n"; - } - - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - - # Modified / Written - if ($Fs::has_mtime{$ftype}) { - if ($sort == $SORT_MOD) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_wr_cur.jpg\" " - . "width=\"89\" height=20 " - . "alt=\"Modified/Written Time\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_MOD"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_wr_link.jpg\" " - . "width=\"60\" height=20 " - . "alt=\"Modified/Written Time\">" - . "</a></td>\n"; - } - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - } - - # Accessed - if ($sort == $SORT_ACC) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_acc_cur.jpg\" " - . "width=\"90\" height=20 " - . "alt=\"Access Time\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_ACC"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_acc_link.jpg\" " - . "width=\"66\" height=20 " - . "alt=\"Access Time\">" - . "</a></td>\n"; - } - - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - - # Change - if ($Fs::has_ctime{$ftype}) { - if ($sort == $SORT_CHG) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_chg_cur.jpg\" " - . "width=\"90\" height=20 " - . "alt=\"Change Time\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_CHG"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_chg_link.jpg\" " - . "width=\"62\" height=20 " - . "alt=\"Change Time\">" - . "</a></td>\n"; - } - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - } - - # Create - if ($Fs::has_crtime{$ftype}) { - if ($sort == $SORT_CRT) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_cre_cur.jpg\" " - . "width=\"84\" height=20 " - . "alt=\"Create Time\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_CRT"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_cre_link.jpg\" " - . "width=\"59\" height=20 " - . "alt=\"Create Time\">" - . "</a></td>\n"; - } - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - } - - # Size - if ($sort == $SORT_SIZE) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_siz_cur.jpg\" " - . "width=\"53\" height=20 " - . "alt=\"Size\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_SIZE"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_siz_link.jpg\" " - . "width=\"31\" height=20 " - . "alt=\"Size\">" - . "</a></td>\n"; - } - - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - - # UID - if ($sort == $SORT_UID) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_uid_cur.jpg\" " - . "width=\"49\" height=20 " - . "alt=\"UID\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_UID"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_uid_link.jpg\" " - . "width=\"27\" height=20 " - . "alt=\"UID\">" - . "</a></td>\n"; - } - - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - - # GID - if ($sort == $SORT_GID) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_gid_cur.jpg\" " - . "width=\"49\" height=20 " - . "alt=\"GID\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_GID"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_gid_link.jpg\" " - . "width=\"28\" height=20 " - . "alt=\"GID\">" - . "</a></td>\n"; - } - - print " <td background=\"$::YEL_PIX\">$sp</td>\n"; - - # meta - if ($sort == $SORT_META) { - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_meta_cur.jpg\" " - . "width=\"62\" height=20 " - . "alt=\"Meta\">" - . "</td>\n"; - } - else { - $iurl = $url . "&sort=$SORT_META"; - print " <td align=\"left\" background=\"$::YEL_PIX\">" - . "<a href=\"$iurl\" target=\"_parent\">" - . "<img border=\"0\" " - . "src=\"pict/file_h_meta_link.jpg\" " - . "width=\"41\" height=20 " - . "alt=\"Meta\">" - . "</a></td>\n"; - } - print "</tr>\n"; - - my $cnt = 0; - my %seen; - - # sort fls into arrays - while ($_ = Exec::read_pipe_line(*OUT)) { - if ( -/^($::REG_MTYPE)\/($::REG_MTYPE)\s*(\*?)\s*($::REG_META)(\(realloc\))?:\t(.+?)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t(\d+)\t(\d+)\t(\d+)$/o - ) - { - - my $lcldir = $Args::args{'dir'}; - $dtype[$cnt] = $1; - $itype[$cnt] = $2; - $del[$cnt] = $3; - $meta[$cnt] = $4; - $realloc[$cnt] = ""; - $realloc[$cnt] = $5 if (defined $5); - $name[$cnt] = $6; - $mod[$cnt] = $7; - $acc[$cnt] = $8; - $chg[$cnt] = $9; - $crt[$cnt] = $10; - $size[$cnt] = $11; - $gid[$cnt] = $12; - $uid[$cnt] = $13; - - if ($meta[$cnt] =~ /^(\d+)(-\d+(-\d+)?)?$/) { - $meta_int[$cnt] = $1; - } - else { - $meta_int[$cnt] = $meta[$cnt]; - } - - # See if we have already seen this file yet - if (exists $seen{"$name[$cnt]-$meta[$cnt]"}) { - my $prev_cnt = $seen{"$name[$cnt]-$meta[$cnt]"}; - - # If we saw it while it was deleted, & it - # is now undel, then update it - if ( ($del[$cnt] eq "") - && ($del[$prev_cnt] eq '*')) - { - $del[$prev_cnt] = $del[$cnt]; - } - next; - - # Add it to the seen list - } - else { - $seen{"$name[$cnt]-$meta[$cnt]"} = $cnt; - } - - # We must adjust the dir for directories - if ($itype[$cnt] eq 'd') { - - # special cases for .. and . - if ($name[$cnt] eq '..') { - my @dirs = split('/', $lcldir); - my $i; - $lcldir = ""; - for ($i = 0; $i < $#dirs; $i++) { - $lcldir .= ($dirs[$i] . '/'); - } - } - elsif ($name[$cnt] ne '.') { - $lcldir .= ($name[$cnt] . '/'); - } - $name[$cnt] .= '/'; - } - else { - $lcldir .= $name[$cnt]; - } - - # format the date so that the time and time zone are on the - # same line - $mod[$cnt] = "$1 $2" - if ($mod[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - - $acc[$cnt] = "$1 $2" - if ($acc[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - - $chg[$cnt] = "$1 $2" - if ($chg[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - - $crt[$cnt] = "$1 $2" - if ($crt[$cnt] =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - - $dir[$cnt] = Args::url_encode($lcldir); - $entry[$cnt] = $cnt; - $cnt++; - - } - - # We missed it for some reason - else { - print -"<tr><td colspan=10>Error Parsing File (Invalid Characters?):<br>$_</td></tr>\n"; - } - } - close(OUT); - - if ($cnt == 0) { - print "</table>\n<center>No Contents</center>\n"; - return 0; - } - - # Sort the above array based on the sort argument - my @sorted; # an array of indices - - if ($sort == $SORT_DTYPE) { - @sorted = - sort { $dtype[$a] cmp $dtype[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_ITYPE) { - @sorted = - sort { $itype[$a] cmp $itype[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_NAME) { - @sorted = sort { lc($name[$a]) cmp lc($name[$b]) } @entry; - } - elsif ($sort == $SORT_MOD) { - @sorted = - sort { $mod[$a] cmp $mod[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_ACC) { - @sorted = - sort { $acc[$a] cmp $acc[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_CHG) { - @sorted = - sort { $chg[$a] cmp $chg[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_CRT) { - @sorted = - sort { $crt[$a] cmp $crt[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_SIZE) { - @sorted = - sort { $size[$a] <=> $size[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_UID) { - @sorted = - sort { $uid[$a] <=> $uid[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_GID) { - @sorted = - sort { $gid[$a] <=> $gid[$b] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - elsif ($sort == $SORT_META) { - @sorted = sort { - $meta_int[$a] <=> $meta_int[$b] - or lc($name[$a]) cmp lc($name[$b]) - } @entry; - } - elsif ($sort == $SORT_DEL) { - @sorted = - sort { $del[$b] cmp $del[$a] or lc($name[$a]) cmp lc($name[$b]) } - @entry; - } - - # print them based on sorting - my $row = 0; - foreach my $i (@sorted) { - my $url; - my $target; - my $color; - my $lcolor; - if ($del[$i] eq '*') { - $color = - "<font color=\"" . $::DEL_COLOR[$realloc[$i] ne ""] . "\">"; - $lcolor = $color; - } - else { - $color = "<font color=\"$::NORM_COLOR\">"; - $lcolor = "<font color=\"$::LINK_COLOR\">"; - } - - # directories have different targets and view values - if ($itype[$i] eq 'd') { - $target = "list"; - $url = - "$::PROGNAME?mod=$::MOD_FILE&view=$File::FILE_LIST&" - . "$Args::baseargs&meta=$meta_int[$i]" - . "&sort=$sort&dir=$dir[$i]&dirmode=$Args::enc_args{'dirmode'}"; - } - else { - $target = "content"; - $url = - "$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&" - . "$Args::baseargs&meta=$meta[$i]" - . "&sort=$sort&dir=$dir[$i]&dirmode=$Args::enc_args{'dirmode'}"; - if ($del[$i] eq '*') { - $url .= "&recmode=$File::REC_YES"; - } - else { - $url .= "&recmode=$File::REC_NO"; - } - } - - if (($row % 2) == 0) { - print -"<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR\">\n <td align=\"center\">"; - } - else { - print -"<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR_TABLE\">\n <td align=\"center\">"; - } - - print "<img src=\"pict/file_b_check.jpg\" border=\"0\">\n" - if ($del[$i] eq '*'); - - print "</td>\n" - . " <td>$sp</td>\n" - . " <td align=\"center\">${color}$dtype[$i] / $itype[$i]</td>\n" - . " <td>$sp</td>\n"; - - # for valid files and directories make a link - # Special rule for $OrphanFiles directory and HFS directories, which have a size of 0 - if ( - ($meta_int[$i] >= $Fs::first_meta{$ftype}) - && (($size[$i] > 0) || (($name[$i] =~ /^\$Orphan/) && ($itype[$i] eq 'd')) || (($ftype =~ /hfs/) && ($itype[$i] eq 'd'))) - && ( ($itype[$i] eq 'r') - || ($itype[$i] eq 'd') - || ($itype[$i] eq 'v')) - ) - { - print " <td><a href=\"$url\" target=\"$target\">$lcolor"; - } - else { - print " <td>$color"; - } - print "<tt>" - . Print::html_encode($name[$i]) - . "</tt></td>\n" - . " <td>$sp</td>\n"; - print " <td>${color}$mod[$i]</td>\n" . " <td>$sp</td>\n" - if ($Fs::has_mtime{$ftype}); - print " <td>${color}$acc[$i]</td>\n" . " <td>$sp</td>\n"; - print " <td>${color}$chg[$i]</td>\n" . " <td>$sp</td>\n" - if ($Fs::has_ctime{$ftype}); - print " <td>${color}$crt[$i]</td>\n" . " <td>$sp</td>\n" - if ($Fs::has_crtime{$ftype}); - print " <td>${color}$size[$i]</td>\n" - . " <td>$sp</td>\n" - . " <td>${color}$uid[$i]</td>\n" - . " <td>$sp</td>\n" - . " <td>${color}$gid[$i]</td>\n" - . " <td>$sp</td>\n"; - - # for a valid meta, make a link to meta browsing mode - if ($meta_int[$i] >= $Fs::first_meta{$ftype}) { - my $iurl = -"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$meta[$i]"; - print "<td><a href=\"$iurl\" target=\"_top\">$lcolor"; - } - else { - print "<td>$color"; - } - print "$meta[$i]</a> $realloc[$i]</td>\n</tr>\n"; - - $row++; - } - - print "</table>\n"; - Print::print_html_footer(); - return 0; - -}; #end of FIL_LIST - -# This takes a directory name as an argument and converts it to -# the meta value and calls FIL_LIST -# -# The meta value can be anything when this is run, it will be -# overwritten -sub file_list_dir { - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $dir = Args::get_dir(); - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - Print::log_host_inv( - "$Args::args{'vol'}: Finding meta data address for $dir"); - - # Use 'ifind -n' to get the meta data address for the given name - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ifind' -f $ftype -n '$dir' -o $offset -i $imgtype $img"); - my $meta; - - while ($_ = Exec::read_pipe_line(*OUT)) { - $meta = $1 - if (/^($::REG_META)$/); - } - close(OUT); - - Print::print_check_err("Error finding meta data address for $dir") - unless (defined $meta); - - Print::print_check_err("Error finding meta data address for $dir: $meta") - unless ($meta =~ /^$::REG_META$/); - - # Verify it is a directory with istat - Exec::exec_pipe(*OUT, - "'$::TSKDIR/istat' -f $ftype -o $offset -i $imgtype $img $meta"); - - while ($_ = Exec::read_pipe_line(*OUT)) { - - # This is a directory - if ( (/mode:\s+d/) - || (/File Attributes: Directory/) - || (/^Flags:.*?Directory/)) - { - close(OUT); - - # Set the meta variables - $Args::enc_args{'meta'} = $Args::args{'meta'} = $meta; - - $Args::args{'dir'} .= "/" - unless ($Args::args{'dir'} =~ /.*?\/$/); - $Args::enc_args{'dir'} .= "/" - unless ($Args::enc_args{'dir'} =~ /.*?\/$/); - - # List the directory contents - file_list(); - - return 0; - } - } - close(OUT); - - # This is not a directory, so just give a link - Print::print_html_header(""); - - my $meta_int = $meta; - $meta_int = $1 if ($meta_int =~ /(\d+)-\d+(-\d+)?/); - - my $recmode = $File::REC_NO; - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ils' -f $ftype -e -o $offset -i $imgtype $img $meta_int"); - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - next unless ($_ =~ /^$meta/); - if ($_ =~ /^$meta\|f/) { - $recmode = $File::REC_YES; - } - elsif ($_ =~ /^$meta\|a/) { - $recmode = $File::REC_NO; - } - else { - Print::print_err("Error parsing ils output: $_"); - } - } - close(OUT); - - print <<EOF; - -<tt>$dir</tt> ( -<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$meta&recmode=$recmode\" target=\"_top\"> -meta $meta</a>) is not a directory. - -<p> -<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&$Args::baseargs&meta=$meta&dir=$dir&recmode=$recmode\" target=\"content\"> - <img src=\"pict/but_viewcont.jpg\" height=20 width=123 alt=\"view contents\" border=\"0\"> -</a> - -EOF - - Print::print_html_footer(); - return 1; - -} - -# List the files that meet a certain pattern -sub file_list_file { - Args::check_sort(); - Args::check_dirmode(); - Args::check_dir(); - - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $ftype = $Caseman::vol2ftype{$vol}; - my $meta = $Fs::root_meta{$ftype}; - my $sort = Args::get_sort(); - my $dirmode = Args::get_dirmode(); - my $dir = Args::get_dir(); - - Print::print_html_header( - "Filtered files on $Caseman::vol2sname{$vol} $mnt"); - - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - my $sp = "  "; - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Listing all files with $dir"); - - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/fls' -f $ftype -lpr $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" - ); - - print "<b>All files with \'<tt>$dir</tt>\' in the name</b><p>\n" - . "<a href=\"$::PROGNAME?$Args::baseargs&dirmode=$Args::enc_args{'dirmode'}" - . "&sort=$sort&mod=$::MOD_FILE&view=$File::FILE_LIST" - . "&meta=$Fs::root_meta{$ftype}&dir=\">" - . "<img border=\"0\" src=\"pict/file_b_allfiles.jpg\" width=\"112\" " - . "alt=\"Show All Files\"></a>\n" . "<hr>" - . "<table cellspacing=\"0\" cellpadding=\"2\" border=0>\n" - . "<tr valign=\"MIDDLE\" align=\"left\" " - . "background=\"$::YEL_PIX\">\n"; - - # deleted - print "<td align=\"left\">" - . "<img border=\"0\" src=\"pict/file_h_del_link.jpg\" " - . "width=\"28\" height=20 alt=\"Deleted Files\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # Type - print "<th align=\"center\">  Type  <br>" - . "dir / in</th>" - . "<td>$sp</td>\n"; - - # Name - print " <td><img border=\"0\" " - . "src=\"pict/file_h_nam_link.jpg\" " - . "width=\"50\" height=20 " - . "alt=\"File Name\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # Mod / Written - if ($Fs::has_mtime{$ftype}) { - print " <td><img border=\"0\" " - . "src=\"pict/file_h_wr_link.jpg\" " - . "width=\"60\" " - . "alt=\"Written Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - } - - # Access - print " <td><img border=\"0\" " - . "src=\"pict/file_h_acc_link.jpg\" " - . "width=\"66\" height=20 " - . "alt=\"Access Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # Change - if ($Fs::has_ctime{$ftype}) { - print " <td><img border=\"0\" " - . "src=\"pict/file_h_chg_link.jpg\" " - . "width=\"62\" " - . "alt=\"Change Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - } - - # Create - if ($Fs::has_crtime{$ftype}) { - print " <td><img border=\"0\" " - . "src=\"pict/file_h_cre_link.jpg\" " - . "width=\"59\" " - . "alt=\"Create Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - } - - # Size - print " <td><img border=\"0\" " - . "src=\"pict/file_h_siz_link.jpg\" " - . "width=\"31\" height=20 " - . "alt=\"Size\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # UID - print " <td><img border=\"0\" " - . "src=\"pict/file_h_uid_link.jpg\" " - . "width=\"27\" height=20 " - . "alt=\"UID\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # GID - print " <td><img border=\"0\" " - . "src=\"pict/file_h_gid_link.jpg\" " - . "width=\"28\" height=20 " - . "alt=\"GID\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # Meta - print " <td><img border=\"0\" " - . "src=\"pict/file_h_meta_link.jpg\" " - . "width=\"41\" height=20 " - . "alt=\"Meta\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - my $row = 0; - while ($_ = Exec::read_pipe_line(*OUT)) { - if ( -/^($::REG_MTYPE)\/($::REG_MTYPE)\s*(\*?)\s*($::REG_META)(\(realloc\))?:\t(.+?)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t(\d+)\t(\d+)\t(\d+)$/o - ) - { - - # We have to remove the / from the beginning of the file name so - # save all values so they aren't lost - my $dt = $1; - my $it = $2; - my $d = $3; - my $i = $4; - my $r = 0; - $r = 1 if (defined $5); - my $n = $6; - my $m = $7; - my $a = $8; - my $c = $9; - my $cr = $10; - my $s = $11; - my $g = $12; - my $u = $13; - - if ($n =~ /^\/(.*)/) { - $n = $1; - } - - my $p = ""; - my $f = $n; - - if ($n =~ /^(.+?)\/([^\/]+)$/) { - $p = $1; - $f = $2; - } - - next unless ($f =~ /$dir/i); - - my $enc_n = Args::url_encode($n); - my $iurl = -"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$i"; - my $i_int = $i; - $i_int = $1 if ($i =~ /(\d+)-\d+-\d+/); - - if (($row % 2) == 0) { - print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR\">\n"; - } - else { - print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR_TABLE\">\n"; - } - - print "<td align=\"left\">\n"; - - my $color; - my $lcolor; - if ($d eq '*') { - $color = "<font color=\"" . $::DEL_COLOR[$r] . "\">"; - $lcolor = $color; - - print "<img src=\"pict/file_b_check.jpg\" border=\"0\">\n"; - - } - else { - $color = "<font color=\"$::NORM_COLOR\">"; - $lcolor = "<font color=\"$::LINK_COLOR\">"; - print " "; - } - - print "</td><td>$sp</td>"; - - print "<td align=\"center\">$color" - . "$dt / $it</td>" - . "<td>$sp</td>\n"; - - if ($it eq 'd') { - my $url = - "$::PROGNAME?mod=$::MOD_FILE&" - . "view=$File::FILE_LIST&$Args::baseargs&meta=$i" - . "&sort=$sort&dir=$enc_n&dirmode=$dirmode"; - - print "<td>"; - if ($i_int >= $Fs::first_meta{$ftype}) { - print "<a href=\"$url\" target=\"_self\">$lcolor"; - } - else { - print "$color"; - } - print "<tt>" - . Print::html_encode($mnt . $n) - . "</tt></td>" - . "<td>$sp</td>\n"; - } - else { - my $url = - "$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&" - . "$Args::baseargs&meta=$i&sort=$sort&dir=$enc_n"; - - if ($d eq '*') { - $url .= "&recmode=$File::REC_YES"; - } - else { - $url .= "&recmode=$File::REC_NO"; - } - - print "<td>"; - if (($i_int >= $Fs::first_meta{$ftype}) && ($it eq 'r')) { - print "<a href=\"$url\" target=\"content\">$lcolor"; - } - else { - print "$color"; - } - print "<tt>$mnt$n</tt></td>" . "<td>$sp</td>\n"; - } - - $m = "$1 $2" - if ($m =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - $a = "$1 $2" - if ($a =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - $c = "$1 $2" - if ($c =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - $cr = "$1 $2" - if ($cr =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - - print "<td>$color$m</td>" . "<td>$sp</td>\n" - if ($Fs::has_mtime{$ftype}); - - print "<td>$color$a</td>" . "<td>$sp</td>\n"; - print "<td>$color$c</td>" . "<td>$sp</td>\n" - if ($Fs::has_ctime{$ftype}); - print "<td>$color$cr</td>" . "<td>$sp</td>\n" - if ($Fs::has_crtime{$ftype}); - - print "<td>$color$s</td>" - . "<td>$sp</td>\n" - . "<td>$color$g</td>" - . "<td>$sp</td>\n" - . "<td>$color$u</td>" - . "<td>$sp</td>\n"; - - print "<td>"; - if ($i_int >= $Fs::first_meta{$ftype}) { - print "<a href=\"$iurl\" target=\"_top\">"; - print "$lcolor$i</a>"; - } - else { - print "$color$i"; - } - print " (realloc)" if $r; - print "</td></tr>\n"; - } - else { - print "Error Parsing File (invalid characters?)<br>: $_\n<br>"; - } - - $row++; - } - close(OUT); - print "</table>\n"; - - print "<center>No files found with that pattern</center>\n" - if ($row == 0); - - Print::print_html_footer(); - return 0; -} - -# display deleted files only -# -# Sorting should be added to this -sub file_list_del { - Args::check_sort(); - Args::check_dirmode(); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $mnt = $Caseman::vol2mnt{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $meta = $Fs::root_meta{$ftype}; - my $sort = Args::get_sort(); - my $dirmode = Args::get_dirmode(); - - Print::print_html_header("Deleted files on $Caseman::vol2sname{$vol} $mnt"); - - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - my $sp = "  "; - - Print::log_host_inv("$Caseman::vol2sname{$vol}: Listing all deleted files"); - - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/fls' -f $ftype -ldr $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" - ); - - print "<b>All Deleted Files</b><p><hr>" - . "<table cellspacing=\"0\" cellpadding=\"2\" border=0>\n" - . "<tr valign=\"MIDDLE\" align=\"left\" " - . "background=\"$::YEL_PIX\">\n"; - - # Type - print "<th align=\"center\">  Type  <br>" - . "dir / in</th>" - . "<td>$sp</td>\n"; - - # Name - print " <td><img border=\"0\" " - . "src=\"pict/file_h_nam_link.jpg\" " - . "width=\"50\" height=20 " - . "alt=\"File Name\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # Mod / Written - if ($Fs::has_mtime{$ftype}) { - print " <td><img border=\"0\" " - . "src=\"pict/file_h_wr_link.jpg\" " - . "width=\"60\" " - . "alt=\"Written Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - } - - # Access - print " <td><img border=\"0\" " - . "src=\"pict/file_h_acc_link.jpg\" " - . "width=\"66\" height=20 " - . "alt=\"Access Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # Change - if ($Fs::has_ctime{$ftype}) { - print " <td><img border=\"0\" " - . "src=\"pict/file_h_chg_link.jpg\" " - . "width=\"62\" " - . "alt=\"Change Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - } - - # Create - if ($Fs::has_crtime{$ftype}) { - print " <td><img border=\"0\" " - . "src=\"pict/file_h_cre_link.jpg\" " - . "width=\"59\" " - . "alt=\"Create Time\">" - . "</td>\n" - . "<td>$sp</td>\n"; - } - - # Size - print " <td><img border=\"0\" " - . "src=\"pict/file_h_siz_link.jpg\" " - . "width=\"31\" height=20 " - . "alt=\"Size\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # UID - print " <td><img border=\"0\" " - . "src=\"pict/file_h_uid_link.jpg\" " - . "width=\"27\" height=20 " - . "alt=\"UID\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # GID - print " <td><img border=\"0\" " - . "src=\"pict/file_h_gid_link.jpg\" " - . "width=\"28\" height=20 " - . "alt=\"GID\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - # Meta - print " <td><img border=\"0\" " - . "src=\"pict/file_h_meta_link.jpg\" " - . "width=\"41\" height=20 " - . "alt=\"Meta\">" - . "</td>\n" - . "<td>$sp</td>\n"; - - my $row = 0; - while ($_ = Exec::read_pipe_line(*OUT)) { - - if ( -/^($::REG_MTYPE)\/($::REG_MTYPE)\s*(\*?)\s*($::REG_META)(\(realloc\))?:\t(.+?)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t($::REG_DATE)\t(\d+)\t(\d+)\t(\d+)$/o - ) - { - - # We have to remove the / from the beginning of the file name so - # save all values so they aren't lost - my $dt = $1; - my $it = $2; - my $d = $3; - my $i = $4; - my $r = 0; - $r = 1 if (defined $5); - my $n = $6; - my $m = $7; - my $a = $8; - my $c = $9; - my $cr = $10; - my $s = $11; - my $g = $12; - my $u = $13; - - if ($n =~ /^\/(.*)/) { - $n = $1; - } - my $enc_n = Args::url_encode($n); - my $iurl = -"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs&meta=$i"; - my $i_int = $i; - $i_int = $1 if ($i =~ /(\d+)-\d+-\d+/); - - if (($row % 2) == 0) { - print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR\">\n"; - } - else { - print "<tr valign=\"TOP\" bgcolor=\"$::BACK_COLOR_TABLE\">\n"; - } - - print "<td align=\"center\"><font color=\"$::DEL_COLOR[$r]\">" - . "$dt / $it</td>" - . "<td>$sp</td>\n"; - - if ($it eq 'd') { - my $url = - "$::PROGNAME?mod=$::MOD_FILE&" - . "view=$File::FILE_LIST&$Args::baseargs&meta=$i" - . "&sort=$sort&dir=$enc_n&dirmode=$dirmode"; - - print "<td>"; - if ($i_int >= $Fs::first_meta{$ftype}) { - print "<a href=\"$url\" target=\"_self\">"; - } - print "<font color=\"$::DEL_COLOR[$r]\"><tt>" - . Print::html_encode($mnt . $n) - . "</tt></td>" - . "<td>$sp</td>\n"; - } - else { - my $url = - "$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&" - . "$Args::baseargs&meta=$i&sort=$sort&dir=$enc_n" - . "&recmode=$File::REC_YES"; - - print "<td>"; - if (($i_int >= $Fs::first_meta{$ftype}) && ($it eq 'r')) { - print "<a href=\"$url\" target=\"content\">"; - } - print "<font color=\"$::DEL_COLOR[$r]\"><tt>" - . Print::html_encode($mnt . $n) - . "</tt></td>" - . "<td>$sp</td>\n"; - } - - $m = "$1 $2" - if ($m =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - $a = "$1 $2" - if ($a =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - $c = "$1 $2" - if ($c =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - $cr = "$1 $2" - if ($cr =~ /($::REG_DAY\s+$::REG_TIME)\s+($::REG_ZONE2)/o); - - print "<td><font color=\"$::DEL_COLOR[$r]\">$m</td>" - . "<td>$sp</td>\n" - if ($Fs::has_mtime{$ftype}); - - print "<td><font color=\"$::DEL_COLOR[$r]\">$a</td>" - . "<td>$sp</td>\n"; - print "<td><font color=\"$::DEL_COLOR[$r]\">$c</td>" - . "<td>$sp</td>\n" - if ($Fs::has_ctime{$ftype}); - print "<td><font color=\"$::DEL_COLOR[$r]\">$cr</td>" - . "<td>$sp</td>\n" - if ($Fs::has_crtime{$ftype}); - - print "<td><font color=\"$::DEL_COLOR[$r]\">$s</td>" - . "<td>$sp</td>\n" - . "<td><font color=\"$::DEL_COLOR[$r]\">$g</td>" - . "<td>$sp</td>\n" - . "<td><font color=\"$::DEL_COLOR[$r]\">$u</td>" - . "<td>$sp</td>\n"; - - print "<td>"; - if ($i_int >= $Fs::first_meta{$ftype}) { - print "<a href=\"$iurl\" target=\"_top\">"; - } - print "<font color=\"$::DEL_COLOR[$r]\">$i</a>"; - print " (realloc)" if $r; - print "</td></tr>\n"; - } - else { - print "Error Parsing File (invalid characters?)<br>: $_\n<br>"; - } - - $row++; - } - close(OUT); - print "</table>\n"; - - print "<center>None</center>\n" - if ($row == 0); - - Print::print_html_footer(); - return 0; -} - -# Content Frame -# This creates two frames for the lower rhs frame -# -sub content_fr { - Print::print_html_header_frameset(""); - - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - print "<frameset rows=\"65,*\">\n"; - - my $recmode = $File::REC_NO; - - if (exists $Args::enc_args{'recmode'}) { - $recmode = $Args::enc_args{'recmode'}; - } - else { - - # We need to get the allocation status of this structure - my $meta_int = $meta; - $meta_int = $1 if ($meta_int =~ /(\d+)-\d+(-\d+)?/); - - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/ils' -f $ftype -e -o $offset -i $imgtype $img $meta_int" - ); - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - next unless ($_ =~ /^$meta/); - if ($_ =~ /^$meta\|f/) { - $recmode = $File::REC_YES; - } - elsif ($_ =~ /^$meta\|a/) { - $recmode = $File::REC_NO; - } - else { - Print::print_check_err("Error parsing ils output: $_"); - } - } - } - close(OUT); - - # Get the file type so we can show the thumb nails automatically - if ($recmode == $File::REC_YES) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - - my $apptype = Exec::read_pipe_line(*OUT); - close(OUT); - - $apptype = "Error getting file type" - if ((!defined $apptype) || ($apptype eq "")); - - # The menu for the different viewing options - print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_MENU&" - . "$Args::baseargs&dir=$Args::enc_args{'dir'}" - . "&meta=$Args::enc_args{'meta'}&sort=$FIL_SORT_ASC&recmode=$recmode\">\n"; - - # Print the image thumbnail - if (($apptype =~ /image data/) || ($apptype =~ /PC bitmap data/)) { - print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_IMG" - . "&$Args::baseargs&dir=$Args::enc_args{'dir'}" - . "&meta=$Args::enc_args{'meta'}" - . "&sort=$FIL_SORT_ASC&recmode=$recmode\" name=\"cont2\">\n</frameset>"; - } - else { - - # Where the actual content will be displayed - print "<frame src=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT" - . "&$Args::baseargs&dir=$Args::enc_args{'dir'}" - . "&meta=$Args::enc_args{'meta'}" - . "&sort=$FIL_SORT_ASC&recmode=$recmode\" name=\"cont2\">\n</frameset>"; - } - - Print::print_html_footer_frameset(); - return 0; -} - -# This is the index for the lower rhs frame -# Choose the content display type here -sub content_menu { - Args::check_sort(); - Args::check_recmode(); - - Print::print_html_header(""); - - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $recmode = Args::get_recmode(); - - # Get the file type - if ($recmode == $File::REC_YES) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - - my $apptype = Exec::read_pipe_line(*OUT); - close(OUT); - - $apptype = "Error getting file type" - if ((!defined $apptype) || ($apptype eq "")); - - # We already have the path in the content window below, so save space - # print "<center><tt>$mnt$Args::args{'dir'}</tt>\n"; - print "<center>\n"; - - my $url = - "&$Args::baseargs&dir=$Args::enc_args{'dir'}" - . "&meta=$Args::enc_args{'meta'}&recmode=$recmode"; - - # Print the options for output display - print "<table cellspacing=\"0\" cellpadding=\"2\">\n<tr>\n" - . "<td>ASCII (<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT&" - . "sort=$FIL_SORT_ASC$url\" target=\"cont2\">display</a> - " - . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::REPORT&" - . "sort=$FIL_SORT_ASC$url\" target=\"_blank\">report</a>)</td>\n" - . "<td>*</td>\n" - . "<td>Hex (" - . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT&" - . "sort=$FIL_SORT_HEX$url\" target=\"cont2\">display</a> - " - . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::REPORT&" - . "sort=$FIL_SORT_HEX$url\" target=\"_blank\">report</a>)</td>\n" - . "<td>*</td>\n" - . "<td>ASCII Strings (" - . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT&" - . "sort=$FIL_SORT_STR$url\" target=\"cont2\">display</a> - " - . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::REPORT&" - . "sort=$FIL_SORT_STR$url\" target=\"_blank\">report</a>)</td>\n" - . "<td>*</td>\n" - . "<td><a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::EXPORT&$url\">" - . "Export</a></td>\n"; - - # if the file is either image or HTML, then let them view it - if ( ($apptype =~ /image data/) - || ($apptype =~ /PC bitmap data/)) - { - print "<td>*</td>\n<td><a href=\"$::PROGNAME?" - . "mod=$::MOD_FILE&view=$File::CONT_IMG$url\"" - . "target=\"cont2\">View</a></td>\n"; - } - elsif ($apptype =~ /HTML document text/) { - print "<td>*</td>\n<td><a href=\"$::PROGNAME?" - . "mod=$::MOD_APPVIEW&view=$Appview::CELL_FRAME$url\"" - . "target=\"_blank\">View</a></td>\n"; - } - - print "<td>*</td>\n" - . "<td><a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::ENTER_FILE$url\" target=\"_blank\">" - . "Add Note</a></td>\n" - if ($::USE_NOTES == 1); - - print "</tr></table>\n"; - - print "File Type: $apptype\n"; - print - "<br><font color=\"$::DEL_COLOR[0]\">Deleted File Recovery Mode</font>\n" - if ($recmode == $File::REC_YES); - print "</center>\n"; - - Print::print_html_footer(); - return 0; -} - -# -# Display the actual content here -# -# NOTE: This has a media type of raw text -# -sub content { - Args::check_sort(); - Args::check_recmode(); - - Print::print_text_header(); - - my $sort = Args::get_sort(); - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $recflag = ""; - $recflag = " -r " if (Args::get_recmode() == $File::REC_YES); - - my $fname = "$mnt$Args::args{'dir'}"; - $fname =~ s/\/\//\//g; - - local *OUT; - if ($sort == $FIL_SORT_ASC) { - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Viewing $fname ($meta) as ASCII"); - - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" - ); - - print "Contents Of File: $fname\n\n\n"; - Print::print_output($_) while ($_ = Exec::read_pipe_data(*OUT, 1024)); - close(OUT); - } - elsif ($sort == $FIL_SORT_HEX) { - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Viewing $fname ($meta) as Hex"); - - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" - ); - - print "Hex Contents Of File: $fname\n\n\n"; - my $offset = 0; - while ($_ = Exec::read_pipe_data(*OUT, 1024)) { - Print::print_hexdump($_, $offset * 1024); - $offset++; - } - close(OUT); - } - elsif ($sort == $FIL_SORT_STR) { - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Viewing $fname ($meta) as strings"); - - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a" - ); - - print "ASCII String Contents Of File: $fname\n\n\n\n"; - Print::print_output($_) while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - } - - Print::print_text_footer(); - - return 0; -} - -sub content_img { - - Print::print_html_header("image content"); - - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - my $fname = "$mnt$Args::args{'dir'}"; - $fname =~ s/\/\//\//g; - - my $url = - "&$Args::baseargs&meta=$Args::enc_args{'meta'}" - . "&dir=$Args::enc_args{'dir'}&" - . "cell_mode=2&recmode=$Args::enc_args{'recmode'}"; - - print "<tt>$fname</tt><br><br>\n" - . "<table><tr>\n" - . "<td width=250 align=\"center\">" - . "<b>Thumbnail:</b><br>" - . "<img src=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_CONT${url}\" width=\"200\"></td>\n" - . "<td valign=top>" - . "<a href=\"$::PROGNAME?mod=$::MOD_APPVIEW&view=$Appview::CELL_CONT${url}\" " - . "target=_blank>View Full Size Image</a><br>\n</td>\n" - . "</tr></table>\n"; - - Print::print_html_footer(); - - return 0; -} - -# Export the contents of a file -sub export { - - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $fname = "$mnt$Args::args{'dir'}"; - $fname =~ s/\/\//\//g; - - my $recflag = ""; - - $recflag = " -r " - if ( (exists $Args::enc_args{'recmode'}) - && ($Args::enc_args{'recmode'} == $File::REC_YES)); - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Saving contents of $fname ($meta)"); - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" - ); - - # We can't trust the mnt and dir values (since there - # could be bad ASCII values, so only allow basic chars into name - $fname =~ tr/a-zA-Z0-9\_\-\@\,/\./c; - $fname = $1 if ($fname =~ /^\.(.*)$/); - - Print::print_oct_header("$vol-${fname}"); - - print "$_" while ($_ = Exec::read_pipe_data(*OUT, 1024)); - - Print::print_oct_footer(); - - return 0; -} - -# Display a report for a file -# This is intended to have its own window -# -sub report { - Args::check_sort(); - - my $sort = Args::get_sort(); - my $vol = Args::get_vol('vol'); - my $meta = Args::get_meta('meta'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $type; - my $fname = "$mnt$Args::args{'dir'}"; - $fname =~ s/\/\//\//g; - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - my $recflag = ""; - - $recflag = " -r " - if ( (exists $Args::enc_args{'recmode'}) - && ($Args::enc_args{'recmode'} == $File::REC_YES)); - - # We can't trust the mnt and dir values (since there - # could be bad ASCII values, so only allow basic chars into name - $fname =~ tr/a-zA-Z0-9\_\-\@\,/\./c; - $fname = $1 if ($fname =~ /^\.+(.*)$/); - $fname = $1 if ($fname =~ /^(.*?)\.+$/); - - Print::print_text_header("filename=$Args::args{'vol'}-${fname}.txt"); - - $fname = "$mnt$Args::args{'dir'}"; - if ($sort == $FIL_SORT_ASC) { - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Generating ASCII report for $fname ($meta)" - ); - $type = "ASCII"; - } - elsif ($sort == $FIL_SORT_HEX) { - Print::log_host_inv( - "$Args::args{'vol'}: Generating Hex report for $fname ($meta)"); - $type = "Hex"; - } - elsif ($sort == $FIL_SORT_STR) { - Print::log_host_inv( -"$Args::args{'vol'}: Generating ASCII strings report for $fname ($meta)" - ); - $type = "string"; - } - else { - print "\n\ninvalid sort value"; - return 1; - } - - # NOTE: There is a space in the beginning of the separator lines in - # order to make clear@stamper.itconsult.co.uk time stamping happy - # I think it confuses the lines that begin at the lhs with PGP - # headers and will remove the second line. - # - print " Autopsy $type Report\n\n" - . "-" x 70 . "\n" - . " GENERAL INFORMATION\n\n" - . "File: $fname\n"; - - # Calculate the MD5 value - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" - ); - my $md5 = Exec::read_pipe_line(*OUT); - close(OUT); - - $md5 = "Error getting MD5 Value" - if ((!defined $md5) || ($md5 eq "")); - - chomp $md5; - if ($recflag eq "") { - print "MD5 of file: $md5\n"; - } - else { - print "MD5 of recovered file: $md5\n"; - } - - if ($::SHA1_EXE ne "") { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" - ); - my $sha1 = Exec::read_pipe_line(*OUT); - close(OUT); - - $sha1 = "Error getting SHA-1 Value" - if ((!defined $sha1) || ($sha1 eq "")); - - chomp $sha1; - if ($recflag eq "") { - print "SHA-1 of file: $sha1\n"; - } - else { - print "SHA-1 of recovered file: $sha1\n"; - } - } - - if ($sort == $FIL_SORT_STR) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a | '$::MD5_EXE'" - ); - $md5 = Exec::read_pipe_line(*OUT); - close(OUT); - - $md5 = "Error getting MD5 Value" - if ((!defined $md5) || ($md5 eq "")); - - chomp $md5; - print "MD5 of ASCII strings: $md5\n"; - - if ($::SHA1_EXE ne "") { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a | '$::SHA1_EXE'" - ); - $sha1 = Exec::read_pipe_line(*OUT); - close(OUT); - - $sha1 = "Error getting SHA-1 Value" - if ((!defined $sha1) || ($sha1 eq "")); - - chomp $sha1; - print "SHA-1 of ASCII strings: $sha1\n"; - } - } - - print "\nImage: $Caseman::vol2path{$vol}\n"; - if (($Caseman::vol2start{$vol} == 0) && ($Caseman::vol2end{$vol} == 0)) { - print "Offset: Full image\n"; - } - elsif ($Caseman::vol2end{$vol} == 0) { - print "Offset: $Caseman::vol2start{$vol} to end\n"; - } - else { - print "Offset: $Caseman::vol2start{$vol} to $Caseman::vol2end{$vol}\n"; - } - print "File System Type: $ftype\n"; - - my $date = localtime(); - print "\nDate Generated: $date\n" - . "Investigator: $Args::args{'inv'}\n\n" - . "-" x 70 . "\n" - . " META DATA INFORMATION\n\n"; - - # Get the meta details - Exec::exec_pipe(*OUT, -"'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" - ); - print $_ while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - - # File Type - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - my $apptype = Exec::read_pipe_line(*OUT); - close(OUT); - - $apptype = "Error getting file type" - if ((!defined $apptype) || ($apptype eq "")); - - print "\nFile Type: $apptype"; - - print "\n" . "-" x 70 . "\n"; - if ($sort == $FIL_SORT_ASC) { - print " CONTENT (Non-ASCII data may not be shown)\n\n"; - } - else { - print " CONTENT\n\n"; - } - - if ($sort == $FIL_SORT_ASC) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" - ); - Print::print_output($_) while ($_ = Exec::read_pipe_data(*OUT, 1024)); - close(OUT); - } - elsif ($sort == $FIL_SORT_HEX) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta" - ); - my $offset = 0; - while ($_ = Exec::read_pipe_data(*OUT, 1024)) { - Print::print_hexdump($_, $offset * 1024); - $offset++; - } - close(OUT); - } - elsif ($sort == $FIL_SORT_STR) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype $recflag -o $offset -i $imgtype $img $meta | '$::TSKDIR/srch_strings' -a" - ); - Print::print_output($_) while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - } - - print "\n" - . "-" x 70 . "\n" - . " VERSION INFORMATION\n\n" - . "Autopsy Version: $::VER\n"; - print "The Sleuth Kit Version: " . ::get_tskver() . "\n"; - - Print::print_text_footer(); - return 0; -} - -# Generate the MD5 value for every file in a given directory and save -# them to a text file -sub md5list { - my $vol = Args::get_vol('vol'); - my $meta = Args::get_meta('meta'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $fname = "$mnt$Args::args{'dir'}"; - $fname = 'root' if ($fname eq '/'); - $fname =~ s/\/\//\//g; - - # We can't trust the mnt and dir values (since there - # could be bad ASCII values, so only allow basic chars into name - $fname =~ tr/a-zA-Z0-9\_\-\@\,/\./c; - - # remove .'s at beginning and end - $fname = $1 if ($fname =~ /^\.+(.*)$/); - $fname = $1 if ($fname =~ /^(.*?)\.+$/); - - Print::print_text_header("filename=$fname.md5"); - - $fname = "$mnt$Args::args{'dir'}"; - $fname =~ s/\/\//\//g; - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/fls' -f $ftype -Fu -o $offset -i $imgtype $img $meta"); - - print "MD5 Values for files in $fname ($Caseman::vol2sname{$vol})\n\n"; - - while ($_ = Exec::read_pipe_line(*OUT)) { - - # area for allocated files - if ( (/r\/[\w\-]\s+([\d\-]+):\s+(.*)$/) - || (/-\/r\s+([\d\-]+):\s+(.*)$/)) - { - my $in = $1; - my $name = $2; - - local *OUT_MD5; - Exec::exec_pipe(*OUT_MD5, -"'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $in | '$::MD5_EXE'" - ); - my $md5out = Exec::read_pipe_line(*OUT_MD5); - - $md5out = "Error calculating MD5" - if ((!defined $md5out) || ($md5out eq "")); - - chomp $md5out; - print "$md5out\t" . Print::html_encode($name) . "\n"; - close(OUT_MD5); - } - elsif (/[\w\-]\/[\w\-]\s+([\d\-]+):\s+(.*)$/) { - - # ignore, non-file types such as sockets or symlinks that do not have - # MD5 values that make sense - } - - # Hmmmm - else { - print "Error parsing file (invalid characters?): $_\n"; - } - } - close(OUT); - - Print::print_text_footer(); - - return 0; -} - -# Blank Page -sub blank { - Print::print_html_header(""); - print "<br><center><h3>File Browsing Mode</h3><br>\n" - . "<p>In this mode, you can view file and directory contents.</p>\n" - . "<p>File contents will be shown in this window.<br>\n" - . "More file details can be found using the Metadata link at the end of the list (on the right).<br>\n" - . "You can also sort the files using the column headers</p>\n"; - Print::print_html_footer(); - return 0; -} - diff --git a/lib/Filesystem.pm b/lib/Filesystem.pm deleted file mode 100644 index 935a22b11b..0000000000 --- a/lib/Filesystem.pm +++ /dev/null @@ -1,170 +0,0 @@ -# -# File system layer functions -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -# Updated 1/13 - -package Filesystem; - -$Filesystem::STATS = 0; - -sub main { - - # By default, show the main window - $Args::args{'view'} = $Args::enc_args{'view'} = $Filesystem::STATS - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - # Check Basic Args - Args::check_vol('vol'); - - # These windows don't need the meta data address - if ($view == $Filesystem::STATS) { - return stats(); - } - else { - Print::print_check_err("Invalid File System View"); - } -} - -sub stats_disk { - Print::print_html_header("Disk Status"); - - my $vol = Args::get_vol('vol'); - my $img = $Caseman::vol2path{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $dtype = $Caseman::vol2dtype{$vol}; - - # Run 'mmls' on the image - Exec::exec_pipe(*OUT, - "'$::TSKDIR/mmls' -o $offset -i $imgtype -t $dtype -r $img"); - - # cycle through results and add each to table with file system type - print "<center><h3>Disk Image Details</h3></center>\n"; - print "<b>PARTITION INFORMATION</b><p>\n"; - - while ($_ = Exec::read_pipe_line(*OUT)) { - print "<tt>$_</tt><br>\n"; - } - return 0; - -} - -############ FILE SYSTEM ################## -sub stats { - - my $vol = Args::get_vol('vol'); - - return stats_disk() if ($Caseman::vol2cat{$vol} eq "disk"); - - Print::print_html_header("File System Status"); - - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Displaying file system details"); - print "<center><h3>General File System Details</h3></center><p>\n"; - - my $fat = 0; - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/fsstat' -f $ftype -o $offset -i $imgtype $img"); - while ($_ = Exec::read_pipe_line(*OUT)) { - - if (/\-\-\-\-\-\-\-\-\-\-/) { - - # Ignore these and print them ahead of the headers - } - - # need the space to prevent NTFS STD_INFORMATION from triggering it - elsif (/ INFORMATION/) { - print "<hr><b>$_</b><p>\n"; - } - elsif (($ftype =~ /fat/) && ($_ =~ /FAT CONTENTS/)) { - print "<hr><b>$_</b><p>\n"; - - # Set the flag if we reach the FAT - $fat = 1; - } - - # Special case for FAT - # We will be giving hyperlinks in the FAT table dump - elsif ($fat == 1) { - - # Ignore the divider - if (/\-\-\-\-\-\-\-\-\-\-/) { - print "$_<br>"; - next; - } - - if (/^((\d+)\-\d+\s+\((\d+)\)) \-\> ([\w]+)$/) { - my $full = $1; - my $blk = $2; - my $len = $3; - my $next = $4; - - # Print the tag so that other FAT entries can link to it - print "<a name=\"$blk\">\n"; - - print -"<a href=\"$::PROGNAME?$Args::baseargs&mod=$::MOD_FRAME&submod=$::MOD_DATA&" - . "block=$blk&len=$len\" target=\"_top\">$full</a> -> "; - - if ($next eq 'EOF') { - print "EOF<br>\n"; - } - else { - print "<a href=\"#$next\">$next</a><br>\n"; - } - } - else { - $fat = 0; - print "$_<br>"; - } - } - else { - print "$_<br>"; - } - } - close(OUT); - - Print::print_html_footer(); - return 0; -} - -1; diff --git a/lib/Frame.pm b/lib/Frame.pm deleted file mode 100644 index 20e107f457..0000000000 --- a/lib/Frame.pm +++ /dev/null @@ -1,336 +0,0 @@ -# -# Functions to create the tabs and frame of the main browsing mode -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -package Frame; - -$Frame::IMG_FRAME = 0; -$Frame::IMG_TABS = 1; -$Frame::IMG_BLANK = 2; - -sub main { - Args::check_vol('vol'); - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $Frame::IMG_FRAME - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - if ($view == $Frame::IMG_FRAME) { - vol_browse_frame(); - } - elsif ($view == $Frame::IMG_TABS) { - vol_browse_tabs(); - } - elsif ($view == $Frame::IMG_BLANK) { - vol_browse_blank(); - } - else { - Print::print_check_err("Invalid Frame View"); - } - - return 0; -} - -# create the frame for the tabs on top and the generic message on the bottom -sub vol_browse_frame { - Print::print_html_header_frameset( - "$Args::args{'case'}:$Args::args{'host'}:$Args::args{'vol'}"); - - my $submod = $::MOD_FRAME; - $submod = Args::get_submod() if (exists $Args::args{'submod'}); - - # Print the rest of the frames - my $str = ""; - my $view = ""; - - if ($submod == $::MOD_FILE) { - $str .= "&meta=$Args::args{'meta'}" if (exists $Args::args{'meta'}); - $str .= "&dir=$Args::args{'dir'}" if (exists $Args::args{'dir'}); - $str .= "&sort=$Args::args{'sort'}" if (exists $Args::args{'sort'}); - $str .= "&dmode=$Args::args{'dmode'}" if (exists $Args::args{'dmode'}); - } - elsif ($submod == $::MOD_DATA) { - $str .= "&block=$Args::args{'block'}" if (exists $Args::args{'block'}); - $str .= "&len=$Args::args{'len'}" if (exists $Args::args{'len'}); - } - elsif ($submod == $::MOD_META) { - $str .= "&meta=$Args::args{'meta'}" if (exists $Args::args{'meta'}); - } - elsif ($submod == $::MOD_FRAME) { - $view = "&view=$Frame::IMG_BLANK"; - } - - print <<EOF; - -<frameset rows=\"40,*\"> - <frame src=\"$::PROGNAME?mod=$::MOD_FRAME&view=$Frame::IMG_TABS&$Args::baseargs&submod=$submod\"> - - <frame src=\"$::PROGNAME?mod=$submod$view&$Args::baseargs$str\"> -</frameset> - -<NOFRAMES> - <center> - Autopsy requires a browser that supports frames. - </center> -</NOFRAMES> - -EOF - - Print::print_html_footer_frameset(); - return 0; -} - -# Display a message when the image is opened (below the tabs) -sub vol_browse_blank { - Print::print_html_header("Main Message"); - - print <<EOF; - -<center> - <br><br><br><br><br><br><br> - To start analyzing this volume, choose an analysis mode from the tabs above. -</center> - -EOF - Print::print_html_footer(); - return 0; -} - -sub vol_browse_tabs { - Args::check_submod(); - Print::print_html_header_tabs("Mode Tabs"); - - my $submod = Args::get_submod(); - my $vol = Args::get_vol('vol'); - - my $special = 0; - $special = 1 - unless (($Caseman::vol2cat{$vol} eq "part") - && ($Fs::is_fs{$Caseman::vol2ftype{$vol}} == 1)); - - # if ( ($Caseman::vol2ftype{$vol} eq "strings") - # || ($Caseman::vol2ftype{$vol} eq "blkls") - # || ($Caseman::vol2ftype{$vol} eq "swap") - # || ($Caseman::vol2ftype{$vol} eq "raw")); - - print "<center><table width=\"800\" border=\"0\" cellspacing=\"0\" " - . "cellpadding=\"0\"><tr>\n"; - - # Files - print "<td align=\"center\" width=116>"; - if ($special == 0) { - - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_FILE&$Args::baseargs\"" - . "target=\"_top\">"; - - # Current - if ($submod == $::MOD_FILE) { - print "<img border=0 " - . "src=\"pict/main_t_fil_cur.jpg\" " - . "width=116 height=38 " - . "alt=\"File Analysis (Current Mode)\"></a>"; - } - - # Link - else { - print "<img border=0 " - . "src=\"pict/main_t_fil_link.jpg\" " - . "width=116 height=38 " - . "alt=\"File Analysis\"></a>"; - } - } - - # non-link - else { - print "<img border=0 " - . "src=\"pict/main_t_fil_org.jpg\" " - . "width=116 height=38 " - . "alt=\"File Analysis (not available)\">"; - } - - # Search - print "</td>\n" . "<td align=\"center\" width=116>"; - - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_KWSRCH&$Args::baseargs\"" - . " target=\"_top\">"; - - if ($submod == $::MOD_KWSRCH) { - print "<img border=0 " - . "src=\"pict/main_t_srch_cur.jpg\" " - . "width=116 height=38 " - . "alt=\"Keyword Search Mode (Current Mode)\"></a>"; - } - else { - print "<img border=0 " - . "src=\"pict/main_t_srch_link.jpg\" " - . "width=116 height=38 " - . "alt=\"Keyword Search Mode\"></a>"; - } - - # File Type - print "</td>\n" . "<td align=\"center\" width=116>"; - - if (($special == 0) && ($::LIVE == 0)) { - - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_APPSORT&$Args::baseargs\"" - . " target=\"_top\">"; - - # Current - if ($submod == $::MOD_APPSORT) { - print "<img border=0 " - . "src=\"pict/main_t_ftype_cur.jpg\" " - . "width=116 height=38 " - . "alt=\"File Type (Current Mode)\"></a>"; - } - else { - print "<img border=0 " - . "src=\"pict/main_t_ftype_link.jpg\" " - . "width=116 height=38 " - . "alt=\"File Type\"></a>"; - } - } - else { - print "<img border=0 " - . "src=\"pict/main_t_ftype_org.jpg\" " - . "width=116 height=38 " - . "alt=\"File Type (not available)\">"; - } - - # Image Details - print "</td>\n" . "<td align=\"center\" width=116>"; - - if (($special == 0) || ($Caseman::vol2cat{$vol} eq "disk")) { - - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_FS&$Args::baseargs\"" - . " target=\"_top\">"; - - if ($submod == $::MOD_FS) { - print "<img border=0 " - . "src=\"pict/main_t_img_cur.jpg\" " - . "width=116 height=38 " - . "alt=\"Image Details Mode (Current Mode)\"></a>"; - } - else { - print "<img border=0 " - . "src=\"pict/main_t_img_link.jpg\" " - . "width=116 height=38 " - . "alt=\"Image Details Mode\"></a>"; - } - } - else { - print "<img border=0 " - . "src=\"pict/main_t_img_org.jpg\" " - . "width=116 height=38 " - . "alt=\"Image Details Mode (not available)\">"; - } - - # Meta Data - print "</td>\n" . "<td align=\"center\" width=116>"; - - if ($special == 0) { - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_META&$Args::baseargs\"" - . " target=\"_top\">"; - - if ($submod == $::MOD_META) { - print "<img border=0 " - . "src=\"pict/main_t_met_cur.jpg\" " - . "width=116 height=38 " - . "alt=\"Meta Data Mode (Current Mode)\"></a>"; - } - else { - print "<img border=0 " - . "src=\"pict/main_t_met_link.jpg\" " - . "width=116 height=38 " - . "alt=\"Meta Data Mode\"></a>"; - } - } - else { - print "<img border=0 " - . "src=\"pict/main_t_met_org.jpg\" " - . "width=116 height=38 " - . "alt=\"Meta Data Mode (not available)\">"; - } - - # Data Units - print "</td>\n" . "<td align=\"center\" width=116>"; - - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_DATA&$Args::baseargs\"" - . " target=\"_top\">"; - - # Current - if ($submod == $::MOD_DATA) { - print "<img border=0 " - . "src=\"pict/main_t_dat_cur.jpg\" " - . "width=116 height=38 " - . "alt=\"Data Units Mode (Current Mode)\"></a>"; - } - - # Link - else { - print "<img border=0 " - . "src=\"pict/main_t_dat_link.jpg\" " - . "width=116 height=38 " - . "alt=\"Data Units Mode\"></a>"; - } - - # Help - set to current mode - print "</td>\n" - . "<td align=\"center\" width=52>" - . "<a href=\"$::HELP_URL\"" - . " target=\"_blank\">" - . "<img border=0 " - . "src=\"pict/tab_help.jpg\" " - . "width=52 " - . "alt=\"Help\">" - . "</a></td>\n"; - - # Close - print "<td align=\"center\" width=52>" - . "<a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::VOL_OPEN&$Args::baseargs_novol\" target=\"_top\">" - . "<img border=0 src=\"pict/tab_close.jpg\" width=52 " - . "alt=\"Close Image\"></a></td>\n"; - - print "</tr></table>\n"; - - Print::print_html_footer_tabs(); - return 0; -} diff --git a/lib/Fs.pm b/lib/Fs.pm deleted file mode 100644 index cc188012b7..0000000000 --- a/lib/Fs.pm +++ /dev/null @@ -1,171 +0,0 @@ -# -package Fs; - -$Fs::types[0] = "ext"; -$Fs::types[1] = "fat"; -$Fs::types[2] = "ntfs"; -$Fs::types[3] = "ufs"; -$Fs::types[4] = "iso9660"; -$Fs::types[5] = "-----"; -$Fs::types[6] = "fat12"; -$Fs::types[7] = "fat16"; -$Fs::types[8] = "fat32"; -$Fs::types[9] = "bsdi"; -$Fs::types[10] = "freebsd"; -$Fs::types[11] = "openbsd"; -$Fs::types[12] = "solaris"; -$Fs::types[13] = "hfs"; - -# These need to be updated as The Sleuth Kit supports more file systems -# -# addr_unit contains the addressable unit per filesystem type -# first_meta contains the first usable meta address on a system -# root_meta is the meta address for the root directory (diff than -# first on ntfs) - -$Fs::addr_unit{'disk'} = 'Sector'; -$Fs::first_addr{'disk'} = 0; -$Fs::is_fs{'disk'} = 0; - -$Fs::addr_unit{'blkls'} = 'Unit'; -$Fs::first_addr{'blkls'} = 0; -$Fs::is_fs{'blkls'} = 0; - -# raw -$Fs::addr_unit{'raw'} = 'Unit'; -$Fs::first_addr{'raw'} = 0; -$Fs::is_fs{'raw'} = 0; - -# Swap -$Fs::addr_unit{'swap'} = 'Unit'; -$Fs::first_addr{'swap'} = 0; -$Fs::is_fs{'swap'} = 0; - -# BSDI -$Fs::first_meta{'bsdi'} = $Fs::root_meta{'bsdi'} = 2; -$Fs::first_addr{'bsdi'} = 0; -$Fs::addr_unit{'bsdi'} = 'Fragment'; -$Fs::has_ctime{'bsdi'} = 1; -$Fs::has_crtime{'bsdi'} = 0; -$Fs::has_mtime{'bsdi'} = 1; -$Fs::meta_str{'bsdi'} = "Inode"; -$Fs::is_fs{'bsdi'} = 1; - -# FreeBSD -$Fs::first_meta{'freebsd'} = $Fs::root_meta{'freebsd'} = 2; -$Fs::first_addr{'freebsd'} = 0; -$Fs::addr_unit{'freebsd'} = 'Fragment'; -$Fs::has_ctime{'freebsd'} = 1; -$Fs::has_crtime{'freebsd'} = 0; -$Fs::has_mtime{'freebsd'} = 1; -$Fs::meta_str{'freebsd'} = "Inode"; -$Fs::is_fs{'freebsd'} = 1; - -# OpenBSD -$Fs::first_meta{'openbsd'} = $Fs::root_meta{'openbsd'} = 2; -$Fs::first_addr{'openbsd'} = 0; -$Fs::addr_unit{'openbsd'} = 'Fragment'; -$Fs::has_ctime{'openbsd'} = 1; -$Fs::has_crtime{'openbsd'} = 0; -$Fs::has_mtime{'openbsd'} = 1; -$Fs::meta_str{'openbsd'} = "Inode"; -$Fs::is_fs{'openbsd'} = 1; - -# Solaris -$Fs::first_meta{'solaris'} = $Fs::root_meta{'solaris'} = 2; -$Fs::first_addr{'solaris'} = 0; -$Fs::addr_unit{'solaris'} = 'Fragment'; -$Fs::has_ctime{'solaris'} = 1; -$Fs::has_crtime{'solaris'} = 0; -$Fs::has_mtime{'solaris'} = 1; -$Fs::meta_str{'solaris'} = "Inode"; -$Fs::is_fs{'solaris'} = 1; - -# UFS -$Fs::first_meta{'ufs'} = $Fs::root_meta{'ufs'} = 2; -$Fs::first_addr{'ufs'} = 0; -$Fs::addr_unit{'ufs'} = 'Fragment'; -$Fs::has_ctime{'ufs'} = 1; -$Fs::has_crtime{'ufs'} = 0; -$Fs::has_mtime{'ufs'} = 1; -$Fs::meta_str{'ufs'} = "Inode"; -$Fs::is_fs{'ufs'} = 1; - -# Linux -$Fs::first_meta{'linux-ext2'} = $Fs::root_meta{'linux-ext2'} = 2; -$Fs::first_addr{'linux-ext2'} = 0; -$Fs::addr_unit{'linux-ext2'} = 'Fragment'; -$Fs::has_ctime{'linux-ext2'} = 1; -$Fs::has_crtime{'linux-ext2'} = 0; -$Fs::has_mtime{'linux-ext2'} = 1; -$Fs::meta_str{'linux-ext2'} = "Inode"; -$Fs::is_fs{'linux-ext2'} = 1; - -$Fs::first_meta{'linux-ext3'} = $Fs::root_meta{'linux-ext3'} = 2; -$Fs::first_addr{'linux-ext3'} = 0; -$Fs::addr_unit{'linux-ext3'} = 'Fragment'; -$Fs::has_ctime{'linux-ext3'} = 1; -$Fs::has_crtime{'linux-ext3'} = 0; -$Fs::has_mtime{'linux-ext3'} = 1; -$Fs::meta_str{'linux-ext3'} = "Inode"; -$Fs::is_fs{'linux-ext3'} = 1; - -$Fs::first_meta{'ext'} = $Fs::root_meta{'ext'} = 2; -$Fs::first_addr{'ext'} = 0; -$Fs::addr_unit{'ext'} = 'Fragment'; -$Fs::has_ctime{'ext'} = 1; -$Fs::has_crtime{'ext'} = 0; -$Fs::has_mtime{'ext'} = 1; -$Fs::meta_str{'ext'} = "Inode"; -$Fs::is_fs{'ext'} = 1; - -# FAT -$Fs::first_meta{'fat'} = $Fs::first_meta{'fat12'} = $Fs::first_meta{'fat16'} = - $Fs::first_meta{'fat32'} = 1; -$Fs::root_meta{'fat'} = $Fs::root_meta{'fat12'} = $Fs::root_meta{'fat16'} = - $Fs::root_meta{'fat32'} = 2; -$Fs::first_addr{'fat'} = $Fs::first_addr{'fat12'} = $Fs::first_addr{'fat16'} = - $Fs::first_addr{'fat32'} = 0; -$Fs::addr_unit{'fat'} = $Fs::addr_unit{'fat12'} = $Fs::addr_unit{'fat16'} = - $Fs::addr_unit{'fat32'} = 'Sector'; -$Fs::has_ctime{'fat'} = $Fs::has_ctime{'fat12'} = $Fs::has_ctime{'fat16'} = - $Fs::has_ctime{'fat32'} = 0; -$Fs::has_crtime{'fat'} = $Fs::has_crtime{'fat12'} = $Fs::has_crtime{'fat16'} = - $Fs::has_crtime{'fat32'} = 1; -$Fs::has_mtime{'fat'} = $Fs::has_mtime{'fat12'} = $Fs::has_mtime{'fat16'} = - $Fs::has_mtime{'fat32'} = 1; -$Fs::meta_str{'fat'} = $Fs::meta_str{'fat12'} = $Fs::meta_str{'fat16'} = - $Fs::meta_str{'fat32'} = "Dir Entry"; -$Fs::is_fs{'fat'} = $Fs::is_fs{'fat12'} = $Fs::is_fs{'fat16'} = - $Fs::is_fs{'fat32'} = 1; - -# NTFS -$Fs::first_meta{'ntfs'} = 0; -$Fs::root_meta{'ntfs'} = 5; -$Fs::first_addr{'ntfs'} = 0; -$Fs::addr_unit{'ntfs'} = 'Cluster'; -$Fs::has_ctime{'ntfs'} = 1; -$Fs::has_crtime{'ntfs'} = 1; -$Fs::has_mtime{'ntfs'} = 1; -$Fs::meta_str{'ntfs'} = "MFT Entry"; -$Fs::is_fs{'ntfs'} = 1; - -# ISO9660 -$Fs::first_meta{'iso9660'} = $Fs::root_meta{'iso9660'} = 0; -$Fs::first_addr{'iso9660'} = 0; -$Fs::addr_unit{'iso9660'} = 'Block'; -$Fs::has_ctime{'iso9660'} = 0; -$Fs::has_crtime{'iso9660'} = 1; -$Fs::has_mtime{'iso9660'} = 0; -$Fs::meta_str{'iso9660'} = "Directory Entry"; -$Fs::is_fs{'iso9660'} = 1; - -# HFS -$Fs::first_meta{'hfs'} = $Fs::root_meta{'hfs'} = 2; -$Fs::first_addr{'hfs'} = 0; -$Fs::addr_unit{'hfs'} = 'Block'; -$Fs::has_ctime{'hfs'} = 1; -$Fs::has_crtime{'hfs'} = 1; -$Fs::has_mtime{'hfs'} = 1; -$Fs::meta_str{'hfs'} = "Record"; -$Fs::is_fs{'hfs'} = 1; diff --git a/lib/Hash.pm b/lib/Hash.pm deleted file mode 100644 index 640e38548e..0000000000 --- a/lib/Hash.pm +++ /dev/null @@ -1,947 +0,0 @@ -# -# Hash database and calculation functions -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2008 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 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. - -package Hash; - -$Hash::DB_MANAGER = 1; -$Hash::DB_LOOKUP = 2; -$Hash::DB_INDEX = 3; -$Hash::IMG_VERIFY = 4; -$Hash::IMG_CALC = 5; -$Hash::IMG_LIST_FR = 6; -$Hash::IMG_LIST = 7; -$Hash::BLANK = 8; - -sub main { - - return if ($::LIVE == 1); - - Args::check_view(); - my $view = Args::get_view(); - - if ($view == $Hash::BLANK) { - blank(); - return 0; - } - elsif ($view == $Hash::DB_MANAGER) { - return db_manager(); - } - elsif ($view == $Hash::DB_LOOKUP) { - return db_lookup(); - } - elsif ($view == $Hash::DB_INDEX) { - return db_index(); - } - elsif ($view == $Hash::IMG_LIST_FR) { - return img_list_fr(); - } - elsif ($view == $Hash::IMG_LIST) { - return img_list(); - } - - Args::check_vol('vol'); - if ($view == $Hash::IMG_CALC) { - return img_calc(); - } - elsif ($view == $Hash::IMG_VERIFY) { - return img_verify(); - } - else { - Print::print_check_err("Invalid Hash View"); - } - -} - -sub index_md5sum { - my $db = shift; - local *OUT; - Exec::exec_pipe(*OUT, "'$::TSKDIR/hfind' -i md5sum '$db'"); - while ($_ = Exec::read_pipe_line(*OUT)) { - print "$_<br>\n"; - } - close(OUT); -} - -sub index_nsrl { - local *OUT; - Exec::exec_pipe(*OUT, "'$::TSKDIR/hfind' -i nsrl-md5 '$::NSRLDB'"); - while ($_ = Exec::read_pipe_line(*OUT)) { - print "$_<br>\n"; - } - close(OUT); -} - -# Manager/status Window from HOST Manager -sub db_manager { - Print::print_html_header("Hash Database Manager"); - - print <<EOF; - -Hash databases allow Autopsy to quickly identify known files. This includes -files that are known to be good and those that are known to be bad. The -'hfind' tool is used to lookup entries in the databases and it needs an -index file for each database. This window allows one to re-index the -database after it has been updated. - -<p> -To edit the location of the databases, you must manually edit the -<tt>host.aut</tt> file in the host directory. - -<hr> -<center> -<img src=\"pict/hashdb_h_alert.jpg\" alt=\"Alert Database\" border=\"0\"> -</center> -<p><b>Overview</b><br> -These files are known to be <U>bad</U> and are the ones that you want to -know about if they are in the image you are analyzing. For example, -this database would include hashes of known attacker tools, rootkits, -or photographs. - -EOF - print "<p><b>Details</b><br>\n"; - if ($Caseman::alert_db eq "") { - print "Location: <tt>Not Configured</tt><br>\n"; - } - elsif (-e "$Caseman::alert_db") { - print "Location: <tt>$Caseman::alert_db</tt><br>\n"; - if (-e "$Caseman::alert_db" . "-md5.idx") { - print "Status: MD5 Index File Exists<br>\n"; - } - else { - print "Status: Database has not been MD5 indexed<br>\n"; - } - - # Index Button - print "<p><a href=\"$::PROGNAME?mod=$::MOD_HASH&" - . "view=$Hash::DB_INDEX&hash_alert=1&$Args::baseargs\">" - . "<img src=\"pict/but_indexdb.jpg\" alt=\"Index DB\" " - . "width=116 height=20 border=\"0\">" - . "</a>\n"; - - # Lookup Button - if (-e "$Caseman::alert_db" . "-md5.idx") { - print "<p><b>Lookup</b><br>" - . "<form action=\"$::PROGNAME\" method=\"get\">" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_HASH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Hash::DB_LOOKUP\">\n" - . "<input type=\"hidden\" name=\"hash_alert\" value=\"1\">\n" - . Args::make_hidden() - . "<table cellspacing=\"10\" cellpadding=\"2\">\n<tr>\n" - . "<td align=\"left\">Enter MD5 Value: " - . "<input type=\"text\" name=\"md5\" size=40 maxlength=32></td>\n" - . "<td align=\"left\">" - . "<input type=\"image\" src=\"pict/but_lookup.jpg\" alt=\"Ok\" " - . "width=116 height=20 border=\"0\">\n" - . "</td></tr>\n</table>\n" - . "</form>"; - } - } - else { - print "Location: <tt>$Caseman::alert_db</tt><br>\n" - . "ERROR: Database not found<br>\n"; - } - - print <<EOF2; -<hr> -<center> -<img src=\"pict/hashdb_h_ig.jpg\" alt=\"Ignore Database\" border=\"0\"> -</center> -<p><b>Overview</b><br> -These files are known to be <U>good</U> and are the ones that you -can ignore if they are found in the image you are analyzing. For -example, this database would include hashes of known system binaries -and other documents that you do not want to waste time on when running -'sorter' or files that you want to confirm were not modified by an -attacker. - -EOF2 - - print "<p><b>Details</b><br>\n"; - if ($Caseman::exclude_db eq "") { - print "Location: <tt>Not Configured</tt><br>\n"; - } - elsif (-e "$Caseman::exclude_db") { - print "Location: <tt>$Caseman::exclude_db</tt><br>\n"; - if (-e "$Caseman::exclude_db" . "-md5.idx") { - print "Status: MD5 Index File Exists<br>\n"; - } - else { - print "Status: Database has not been MD5 indexed<br>\n"; - } - - # Index Button - print "<p><a href=\"$::PROGNAME?mod=$::MOD_HASH&view=$Hash::DB_INDEX&" - . "hash_exclude=1&$Args::baseargs\">" - . "<img src=\"pict/but_indexdb.jpg\" alt=\"Index DB\" " - . "width=116 height=20 border=\"0\">" - . "</a>\n"; - - # Lookup Button - if (-e "$Caseman::exclude_db" . "-md5.idx") { - print "<p><b>Lookup</b><br>" - . "<form action=\"$::PROGNAME\" method=\"get\">" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_HASH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Hash::DB_LOOKUP\">\n" - . "<input type=\"hidden\" name=\"hash_exclude\" value=\"1\">\n" - . Args::make_hidden() - . "<table cellspacing=\"10\" cellpadding=\"2\">\n<tr>\n" - . "<td align=\"left\">Enter MD5 Value: " - . "<input type=\"text\" name=\"md5\" size=40 maxlength=32></td>\n" - . "<td align=\"left\">" - . "<input type=\"image\" src=\"pict/but_lookup.jpg\" alt=\"Ok\" " - . "width=116 height=20 border=\"0\">\n" - . "</td></tr>\n</table>\n" - . "</form>"; - } - } - else { - print "Location: <tt>$Caseman::exclude_db</tt><br>\n" - . "ERROR: Database not found<br>\n"; - } - - print <<EOF3; -<hr> -<center> -<img src=\"pict/hashdb_h_nsrl.jpg\" alt=\"NSRL Database\" border=\"0\"> -</center> -<p><b>Overview</b><br> -These files are known to be <U>good</U> and <U>bad</U>. It is currently -difficult to distinguish between known good and known bad, but the NSRL -is used in Autopsy to ignore all known files. - -EOF3 - - print "<p><b>Details</b><br>\n"; - if ($::NSRLDB eq "") { - print "Location: <tt>Not Configured</tt><br>\n"; - } - elsif (-e "$::NSRLDB") { - print "Location: <tt>$::NSRLDB</tt><br>\n"; - if (-e "$::NSRLDB" . "-md5.idx") { - print "Status: MD5 Index File Exists<br>\n"; - } - else { - print "Status: Database has not been MD5 indexed<br>\n"; - } - - # Index Button - print "<p><a href=\"$::PROGNAME?mod=$::MOD_HASH&view=$Hash::DB_INDEX&" - . "hash_nsrl=1&$Args::baseargs\">" - . "<img src=\"pict/but_indexdb.jpg\" alt=\"Index DB\" " - . "width=116 height=20 border=\"0\">" - . "</a>\n"; - - # Lookup Button - if (-e "$::NSRLDB" . "-md5.idx") { - print "<p><b>Lookup</b><br>" - . "<form action=\"$::PROGNAME\" method=\"get\">" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_HASH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Hash::DB_LOOKUP\">\n" - . "<input type=\"hidden\" name=\"hash_nsrl\" value=\"1\">\n" - . Args::make_hidden() - . "<table cellspacing=\"10\" cellpadding=\"2\">\n<tr>\n" - . "<td align=\"left\">Enter MD5 Value: " - . "<input type=\"text\" name=\"md5\" size=40 maxlength=32></td>\n" - . "<td align=\"left\">" - . "<input type=\"image\" src=\"pict/but_lookup.jpg\" " - . "alt=\"Lookup\" width=116 height=20 border=0>\n" - . "</td></tr>\n</table>\n" - . "</form>"; - } - } - else { - print "Location: <tt>$::NSRLDB</tt><br>\n" - . "ERROR: Database not found<br>\n"; - } - - print <<EOF4; - -<hr><center> -<table width=600 cellspacing=\"0\" cellpadding=\"2\"> -<tr> - <td align=center> - <a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::VOL_OPEN&$Args::baseargs\"> - <img src=\"pict/menu_b_close.jpg\" alt=\"Close\" width=\"167\" height=20 border=\"0\"> - </a> - </td> - <td align=center> - <a href=\"$::HELP_URL\" target=\"_blank\"> - <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" - width=\"167\" height=20 border=0> - </a> - </td> -</tr> -</table> -EOF4 - - Print::print_html_footer(); - return 0; -} - -sub db_index { - Print::print_html_header("Hash Database Indexing"); - - if ( (exists $Args::args{'hash_exclude'}) - && ($Args::args{'hash_exclude'} == 1) - && ($Caseman::exclude_db ne "")) - { - Print::log_host_info("Exclude Database Re-Indexed"); - print "<hr><b>Exclude Database Indexing</b><p>\n"; - index_md5sum($Caseman::exclude_db); - } - - if ( (exists $Args::args{'hash_alert'}) - && ($Args::args{'hash_alert'} == 1) - && ($Caseman::alert_db ne "")) - { - Print::log_host_info("Alert Database Re-Indexed"); - print "<hr><b>Alert Database Indexing</b><p>\n"; - index_md5sum($Caseman::alert_db); - } - - if ( (exists $Args::args{'hash_nsrl'}) - && ($Args::args{'hash_nsrl'} == 1) - && ($::NSRLDB ne "")) - { - Print::log_host_info("NSRL Database Re-Indexed"); - print "<hr><b>NSRL Database Indexing</b><p>\n"; - index_nsrl(); - } - - print "<p>Indexing Complete<br>\n" - . "<hr><p>\n<a href=\"$::PROGNAME?mod=$::MOD_HASH&view=$Hash::DB_MANAGER&" - . "$Args::baseargs\">\n" - . "<img src=\"pict/menu_b_hashdb.jpg\" width=\"167\" " - . "height=20 alt=\"Hash Databases\" border=\"0\"></a>\n"; - - Print::print_html_footer(); - return 0; -} - -# Lookup hashes in database -sub db_lookup { - Print::print_html_header("Hash Database Lookup"); - - unless ((exists $Args::args{'md5'}) - && ($Args::args{'md5'} =~ /^$::REG_MD5$/o)) - { - Print::print_err("Invalid MD5 Argument"); - } - - if ( (exists $Args::args{'hash_nsrl'}) - && ($Args::args{'hash_nsrl'} == 1) - && ($::NSRLDB ne "")) - { - print "<hr><b>NSRL Lookup</b><p>\n"; - - if (-e "$::NSRLDB") { - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/hfind' '$::NSRLDB' $Args::args{'md5'}"); - print "$_<br>\n" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - Print::log_host_inv("NSRL Lookup ($Args::args{'md5'})"); - } - else { - print "NSRL Database Missing<br>\n"; - Print::log_host_inv( - "NSRL Lookup ($Args::args{'md5'}) - Database Missing"); - } - } - - if ( (exists $Args::args{'hash_exclude'}) - && ($Args::args{'hash_exclude'} == 1) - && ($Caseman::exclude_db ne "")) - { - print "<hr><b>Exclude Database Lookup</b><p>\n"; - - if (-e "$Caseman::exclude_db") { - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/hfind' '$Caseman::exclude_db' $Args::args{'md5'}"); - print "$_<br>\n" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - Print::log_host_inv("Exclude Database Lookup ($Args::args{'md5'})"); - } - else { - print "Exclude Database Missing<br>\n"; - Print::log_host_inv( -"Exclude Database Lookup ($Args::args{'md5'}) - Database Missing" - ); - } - } - - if ( (exists $Args::args{'hash_alert'}) - && ($Args::args{'hash_alert'} == 1) - && ($Caseman::alert_db ne "")) - { - print "<hr><b>Alert Database Lookup</b><p>\n"; - - if (-e "$Caseman::alert_db") { - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/hfind' '$Caseman::alert_db' $Args::args{'md5'}"); - print "$_<br>\n" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - Print::log_host_inv("Alert Database Lookup ($Args::args{'md5'})"); - } - else { - print "Alert Database Missing<br>\n"; - Print::log_host_inv( - "Alert Database Lookup ($Args::args{'md5'}) - Database Missing" - ); - } - } - - print "<hr><p>\n" - . "If any of the hash databases need to be re-indexed, use the " - . "<U>Hash Database Manager</U><p>" - . "<a href=\"$::PROGNAME?mod=$::MOD_HASH&view=$Hash::DB_MANAGER&" - . "$Args::baseargs\" target=\"_top\">\n" - . "<img src=\"pict/menu_b_hashdb.jpg\" width=\"167\" " - . "height=20 alt=\"Hash Databases\" border=\"0\"></a>\n"; - - Print::print_html_footer(); - return 0; -} - -############ INTEGRITY CHECKS ################## - -# Special view for printing integrity check menu -# We show any file that we have a reference for - -# pass the md5 hash (from md5.txt) and then the sorted array -sub int_menu_print { - my %md5s = %{$_[0]}; - my @sort = @{$_[1]}; - - for (my $i = 0; $i <= $#sort; $i++) { - - print -"<tr><td align=\"right\"><tt><b>$Caseman::vol2sname{$sort[$i]}</b></tt></td>\n"; - - # It already exists, so make verify button - if (exists $md5s{$sort[$i]}) { - print "<td><tt>$md5s{$sort[$i]}</tt></td><td>" - . "<form action=\"$::PROGNAME\" method=\"get\" target=\"cont\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$sort[$i]\">\n" - . Args::make_hidden() - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_HASH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Hash::IMG_VERIFY\">\n" - . "<input type=\"image\" src=\"pict/int_b_valid.jpg\" " - . "alt=\"Validate\" border=\"0\">\n" - . "</form></td></tr>\n"; - } - - # we currenly only support integrity for raw and split image formats - elsif (($Caseman::vol2itype{$sort[$i]} ne "raw") - && ($Caseman::vol2itype{$sort[$i]} ne "split")) - { - print -"<td colspan=2>Integrity checks for image type $Caseman::vol2itype{$sort[$i]} not yet supported</td></tr>\n"; - } - - # Generate New button - else { - print "<td> </td><td>" - . "<form action=\"$::PROGNAME\" method=\"get\" target=\"cont\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$sort[$i]\">\n" - . Args::make_hidden() - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_HASH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Hash::IMG_CALC\">\n" - . "<input type=\"image\" src=\"pict/int_b_calc.jpg\" " - . "alt=\"Calculate\" border=\"0\">\n" - . "</form></td></tr>\n"; - } - } - - return; -} - -# Create a frame with two rows, one with the list of images to check -# and then the bottom actually does it. -sub img_list_fr { - Print::print_html_header_frameset( - "$Args::args{'case'}:$Args::args{'host'} Integrity Check"); - - print "<frameset rows=\"80%,20%\">\n"; - - # Block List - print "<frame src=\"$::PROGNAME?mod=$::MOD_HASH&view=$Hash::IMG_LIST&" - . "$Args::baseargs\">\n" - . "<frame src=\"$::PROGNAME?mod=$::MOD_HASH&view=$Hash::BLANK&" - . "$Args::baseargs\" name=\"cont\">\n" - . "</frameset>\n"; - - Print::print_html_footer_frameset(); - return 0; -} - -# Reads the MD5 file to fill in the MENU list for the integrity -# check mode -sub img_list { - Print::print_html_header("Image Integrity Menu"); - - my %md5s; - my @blkls; - my @str; - my @img; - my @body; - my @tl; - - # Read the known values if the file exists - if (open(FILE, "$::host_dir" . "/md5.txt")) { - - # Read the md5 values into a hash - while (<FILE>) { - s/^\s+//; - s/\s+$//; - - if (/($::REG_MD5)\s+(.*)/o) { - $md5s{"$2"} = $1; - $md5s{"$2"} =~ tr/[a-f]/[A-F]/; - } - else { - print "Error reading line $. of md5.txt: $_<br>\n"; - return 1; - } - } - close(FILE); - } - - # sort the images into the different types - foreach my $k (keys %Caseman::vol2cat) { - if ($Caseman::vol2cat{$k} eq "image") { - push @img, $k; - } - elsif ($Caseman::vol2ftype{$k} eq "blkls") { - push @blkls, $k; - } - elsif ($Caseman::vol2ftype{$k} eq "strings") { - push @str, $k; - } - elsif ($Caseman::vol2ftype{$k} eq "body") { - push @body, $k; - } - elsif ($Caseman::vol2ftype{$k} eq "timeline") { - push @tl, $k; - } - } - - print "<center><table cellspacing=\"10\" cellpadding=\"2\">"; - - # image files - if (scalar @img > 0) { - print "<tr><th colspan=3>" - . "<img src=\"pict/int_h_img.jpg\" alt=\"Image Files\">" - . "</th></tr>\n"; - my @sort = sort { $a cmp $b } @img; - int_menu_print(\%md5s, \@sort); - } - - # Unallocated (blkls) images - if (scalar @blkls > 0) { - print "<tr><th colspan=3> </th></tr>\n" - . "<tr><th colspan=3>" - . "<img src=\"pict/int_h_unalloc.jpg\" alt=\"Unallocated Data Files\">" - . "</th></tr>\n"; - my @sort = sort { $a cmp $b } @blkls; - int_menu_print(\%md5s, \@sort); - } - - # Strings files (of blkls or fs images) - if (scalar @str > 0) { - print "<tr><th colspan=3> </th></tr>\n" - . "<tr><th colspan=3>" - . "<img src=\"pict/int_h_str.jpg\" alt=\"Strings of Images\">" - . "</th></tr>\n"; - my @sort = sort { $a cmp $b } @str; - int_menu_print(\%md5s, \@sort); - - } - - # timeline body files - if (scalar @body > 0) { - print "<tr><th colspan=3> </th></tr>\n" - . "<tr><th colspan=3>" - . "<img src=\"pict/int_h_data.jpg\" alt=\"Timeline Data Files\">" - . "</th></tr>\n"; - my @sort = sort { $a cmp $b } @body; - int_menu_print(\%md5s, \@sort); - } - - # timeline files - if (scalar @tl > 0) { - print "<tr><th colspan=3> </th></tr>\n" - . "<tr><th colspan=3>" - . "<img src=\"pict/int_h_tl.jpg\" alt=\"Timelines\">" - . "</th></tr>\n"; - my @sort = sort { $a cmp $b } @tl; - int_menu_print(\%md5s, \@sort); - } - - print <<EOF; -</table> -<p> -<table cellspacing=20 width=600 cellpadding=2> -<tr> - <td><a href=\"$::PROGNAME?$Args::baseargs&mod=$::MOD_CASEMAN&view=$Caseman::VOL_OPEN\" target=\"_top\"> - <img src=\"pict/menu_b_close.jpg\" alt=\"close\" - width=\"167\" height=20 border=\"0\"> - </a> - </td> - <td><a href=\"$::PROGNAME?$Args::baseargs&mod=$::MOD_HASH&view=$Hash::IMG_LIST_FR\" target=\"_top\"> - <img src=\"pict/menu_b_ref.jpg\" alt=\"Refresh\" - width=\"167\" height=20 border=\"0\"> - </a> - </td> - <td align=center> - <a href=\"$::HELP_URL\" target=\"_blank\"> - <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" - width=\"167\" height=20 border=0> - </a> - </td> -</tr> -</table> - -EOF - Print::print_html_footer(); - return 0; -} - -# Pass the relative path (images/xyz) of the file. The MD5 is -# returned (or NULL) (in all caps) -sub lookup_md5 { - my $vol = shift; - my $md5 = ""; - - my $md5_file = "$::host_dir/md5.txt"; - - if (-e "$md5_file") { - unless (open(FILE, $md5_file)) { - print "Error opening $md5_file<br>\n"; - return ""; - } - - while (<FILE>) { - s/^\s+//; - s/\s+$//; - - if (/($::REG_MD5)\s+(.*)/o) { - my $m = $1; - if ($2 =~ /$vol$/) { - $md5 = $m; - $md5 =~ tr/[a-f]/[A-F]/; - last; - } - } - else { - print "Error reading line $. of $md5_file: $_<br>\n"; - return ""; - } - } - close(FILE); - } - - return $md5; -} - -sub img_verify { - - Print::print_html_header("Image Integrity Check"); - - my $vol = Args::get_vol('vol'); - - my $md5 = lookup_md5($vol); - - if ($md5 eq "") { - print -"The MD5 value of <tt>$Caseman::vol2sname{$vol}</tt> was not found<br>" - . "It can be calculated by pressing the button below." - . "<br><br>\n<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_HASH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Hash::IMG_CALC\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/int_b_calc.jpg\" " - . "alt=\"Calculate\" border=\"0\">\n</form>"; - return 1; - } - - Print::log_host_inv("$Caseman::vol2sname{$vol}: Checking image integrity"); - - print "Original MD5: <tt>$md5</tt><br>\n"; - - # We have the original value, now get the new one - my $img = $Caseman::vol2path{$vol}; - - my $cur; - if ($Caseman::vol2itype{$vol} eq "split") { - $cur = calc_md5_split($img); - } - else { - $cur = calc_md5($img); - } - - if ($cur =~ /^$::REG_MD5$/o) { - print "Current MD5: <tt>$cur</tt><br><br>\n"; - - if ($cur eq $md5) { - print "Pass<br>\n"; - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Image integrity check PASSED"); - } - else { - print "<font color=\"$::DEL_COLOR[0]\">Fail: Restore from backup" - . "<br>\n"; - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: Image integrity check FAILED"); - } - Print::print_html_footer(); - return 0; - } - else { - print "$cur<br>\n"; - Print::print_html_footer(); - return 1; - } -} - -# Calculate the MD5 value of a file (given the full path) -# return the value in upper case -# This one supports only single files - not split volumes -sub calc_md5 { - my $img = shift; - - my $hit_cnt = 0; - $SIG{ALRM} = sub { - if (($hit_cnt++ % 5) == 0) { - print "+"; - } - else { - print "-"; - } - alarm(5); - }; - - alarm(5); - local *OUT; - Exec::exec_pipe(*OUT, "'$::MD5_EXE' $img"); - - alarm(0); - $SIG{ALRM} = 'DEFAULT'; - print "<br>\n" - if ($hit_cnt > 0); - - my $out = Exec::read_pipe_line(*OUT); - close(OUT); - - $out = "Error calculating MD5" - if ((!defined $out) || ($out eq "")); - - if ($out =~ /^($::REG_MD5)\s+/) { - my $m = $1; - $m =~ tr/[a-f]/[A-F]/; - return $m; - } - else { - return $out; - } -} - -# Same as the version above, but this one can do split images -# it fails though if the file is not a multiple of 512 -sub calc_md5_split { - my $img = shift; - - my $hit_cnt = 0; - $SIG{ALRM} = sub { - if (($hit_cnt++ % 5) == 0) { - print "+"; - } - else { - print "-"; - } - alarm(5); - }; - - alarm(5); - local *OUT; - - # We use the blkls method so that we can handle split images - Exec::exec_pipe(*OUT, "'$::TSKDIR/blkls' -f raw -e $img | '$::MD5_EXE'"); - - alarm(0); - $SIG{ALRM} = 'DEFAULT'; - print "<br>\n" - if ($hit_cnt > 0); - - my $out = Exec::read_pipe_line(*OUT); - close(OUT); - - $out = "Error calculating MD5" - if ((!defined $out) || ($out eq "")); - - if ($out =~ /^($::REG_MD5)\s+/) { - my $m = $1; - $m =~ tr/[a-f]/[A-F]/; - return $m; - } - else { - return $out; - } -} - -# Pass it the full path and the short name -# and it adds it to md5.txt and returns the MD5 -sub int_create_wrap { - my $vol = shift; - my $img = $Caseman::vol2path{$vol}; - - my $m; - if ( (exists $Caseman::vol2itype{$vol}) - && ($Caseman::vol2itype{$vol} eq "split")) - { - $m = calc_md5_split($img); - } - else { - $m = calc_md5($img); - } - Caseman::update_md5($vol, $m) if ($m =~ /^$::REG_MD5$/o); - return $m; -} - -sub img_calc { - Print::print_html_header("Image Integrity Creation"); - my $vol = Args::get_vol('vol'); - print "Calculating MD5 value for <tt>$Caseman::vol2sname{$vol}</tt><br>\n"; - Print::log_host_inv("$Caseman::vol2sname{$vol}: Calculating MD5 value"); - - my $m = int_create_wrap($vol); - - print "MD5: <tt>$m</tt><br>\n"; - print "<br>Value saved to host file<br><br>\n"; - - Print::print_html_footer(); - return 0; -} - -# Conver the 'image' format to the 'volume' format -# Make one central file -sub convert { - my %img2vol = %{shift()}; - - Print::log_host_info("Converting format of MD5 hash files"); - - # Get out of here if there are no hash files - return 0 - unless ((-e "$::host_dir" . "$::IMGDIR" . "/md5.txt") - || (-e "$::host_dir" . "$::DATADIR" . "/md5.txt")); - - # We are going ot make a single file - my $md5_file_new = "$::host_dir" . "/md5.txt"; - open MD5_NEW, ">$md5_file_new" - or die "Can't open writing file: $md5_file_new"; - - # Read the md5s for the image directory - my $md5_file = "$::host_dir" . "$::IMGDIR" . "/md5.txt"; - if (open(FILE, $md5_file)) { - - # Read the md5 values into a hash - while (<FILE>) { - s/^\s+//; - s/\s+$//; - - if (/($::REG_MD5)\s+(.*)/o) { - my $md5 = $1; - my $img = $2; - - unless (exists $img2vol{$img}) { - print STDERR -"Error finding image during hash file conversion: $img. Skipping\n"; - next; - } - my $vol = $img2vol{$img}; - - print MD5_NEW "$md5 $vol\n"; - } - else { - print MD5_NEW "$_"; - } - } - close(FILE); - rename $md5_file, $md5_file . ".bak"; - } - - # Now do the data directory - $md5_file = "$::host_dir" . "$::DATADIR" . "/md5.txt"; - if (open(FILE, $md5_file)) { - - # Read the md5 values into a hash - while (<FILE>) { - s/^\s+//; - s/\s+$//; - - if (/($::REG_MD5)\s+(.*)/o) { - my $md5 = $1; - my $img = $2; - - unless (exists $img2vol{$img}) { - print STDERR -"Error finding image during hash file conversion: $img. Skipping\n"; - next; - } - my $vol = $img2vol{$img}; - - print MD5_NEW "$md5 $vol\n"; - } - else { - print MD5_NEW "$_"; - } - } - close(FILE); - rename $md5_file, $md5_file . ".bak"; - } - - close(MD5_NEW); - return 0; -} - -# Blank Page -sub blank { - Print::print_html_header(""); - print "<!-- This Page Intentionally Left Blank -->\n"; - Print::print_html_footer(); - return 0; -} diff --git a/lib/Kwsrch.pm b/lib/Kwsrch.pm deleted file mode 100644 index a643bfa7bf..0000000000 --- a/lib/Kwsrch.pm +++ /dev/null @@ -1,954 +0,0 @@ -# -# Keyword search mode -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -package Kwsrch; - -require 'search.pl'; - -$Kwsrch::ENTER = 1; -$Kwsrch::RESULTS_FR = 2; -$Kwsrch::RUN = 3; -$Kwsrch::LOAD = 4; -$Kwsrch::BLANK = 5; - -my $IMG_DETAILS = 0x80; - -sub main { - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $Kwsrch::ENTER - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - if ($view == $Kwsrch::BLANK) { - blank(); - return 0; - } - - # Check Basic Args - Args::check_vol('vol'); - - # These windows don't need the meta data address - if ($view == $Kwsrch::ENTER) { - return enter(); - } - elsif ($view == $Kwsrch::RESULTS_FR) { - return results_fr(); - } - elsif ($view == $Kwsrch::RUN) { - return run(); - } - elsif ($view == $Kwsrch::LOAD) { - return load(); - } - else { - Print::print_check_err("Invalid Keyword Search View"); - } -} - -my $CASE_INSENS = 1; -my $CASE_SENS = 0; - -my $REG_EXP = 1; -my $STRING = 0; - -# Form to enter search data -sub enter { - my $vol = Args::get_vol('vol'); - - Print::print_html_header("Search on $Caseman::vol2sname{$vol}"); - my $ftype = $Caseman::vol2ftype{$vol}; - - if ($ftype eq 'blkls') { - print "<center><h3>Keyword Search of Unallocated Space</h3>\n"; - } - elsif ($ftype eq 'swap') { - print "<center><h3>Keyword Search of swap partition</h3>\n"; - } - elsif ($ftype eq 'raw') { - print "<center><h3>Keyword Search of raw data</h3>\n"; - } - elsif ($Caseman::vol2cat{$vol} eq "disk") { - print "<center><h3>Keyword Search of disk</h3>\n"; - } - else { - print -"<center><h3>Keyword Search of Allocated and Unallocated Space</h3>\n"; - } - - # @@@ Fix this - caused by writing all results to a file - if ($::LIVE == 1) { - Print::print_err( -"Keyword searching is temporarily not available during live analysis mode" - ); - } - - print "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "Enter the keyword string or expression to search for:<br> <input type=\"text\" name=\"str\"><br><br>\n" - . Args::make_hidden() - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_KWSRCH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Kwsrch::RESULTS_FR\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n"; - - print "<table width=400><tr>\n" - . "<td width=200 align=center><input type=\"checkbox\" name=\"ascii\" value=\"1\" CHECKED>" - . "ASCII \n</td>" - . "<td width=200 align=center><input type=\"checkbox\" name=\"unicode\" value=\"1\" CHECKED>" - . "Unicode</td></tr>\n" - . "<tr><td align=center><input type=\"checkbox\" name=\"srch_case\" value=\"$CASE_INSENS\">" - . "Case Insensitive</td>\n" - . "<td align=center><input type=\"checkbox\" name=\"regexp\" value=\"$REG_EXP\">\n" - . "<tt>grep</tt> Regular Expression</td></tr></table>\n" - . "<input type=\"image\" src=\"pict/but_search.jpg\" " - . "alt=\"Search\" border=\"0\">\n</form>\n"; - - if ($::LIVE == 0) { - print "<table width=600><tr>\n"; - - # If we are a non-blkls image and one exists - make a button to load it - if (($ftype ne 'blkls') && (exists $Caseman::vol2blkls{$vol})) { - print "<td align=center width=200>" - . "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" - . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_KWSRCH\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$Caseman::vol2blkls{$vol}\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/srch_b_lun.jpg\" " - . "alt=\"Load Unallocated Image\" border=\"0\">\n<br></form></td>\n"; - } - - # If we are a blkls and the original exists - make a button to load it - elsif (($ftype eq 'blkls') - && (exists $Caseman::mod2vol{$vol})) - { - print "<td align=center width=200>" - . "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_FRAME\">\n" - . "<input type=\"hidden\" name=\"submod\" value=\"$::MOD_KWSRCH\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$Caseman::mod2vol{$vol}\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/srch_b_lorig.jpg\" " - . "alt=\"Load Original Image\" border=\"0\">\n<br></form></td>\n"; - } - - # Strings Button - if ( (!(exists $Caseman::vol2str{$vol})) - || (!(exists $Caseman::vol2uni{$vol}))) - { - - my $dest_vol = $vol; - $dest_vol = $Caseman::mod2vol{$vol} - if exists($Caseman::mod2vol{$vol}); - - print "<td align=center width=200>" - . "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_DETAILS\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$dest_vol\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/srch_b_str.jpg\" " - . "alt=\"Extract Strings\" border=\"0\">\n<br></form></td>\n"; - } - - # Unallocated Space Button - if ( ($Fs::is_fs{$ftype}) - && (!(exists $Caseman::vol2blkls{$vol}))) - { - print "<td align=center width=200>" - . "<form action=\"$::PROGNAME\" method=\"get\" target=\"_top\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_CASEMAN\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Caseman::VOL_DETAILS\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . Args::make_hidden() - . "<input type=\"image\" src=\"pict/srch_b_un.jpg\" " - . "alt=\"Extract Unallocated Space\" border=\"0\">\n<br></form></td>\n"; - } - - print "</tr></table>\n"; - } - - print "<a href=\"help/grep.html\" target=\"_blank\">" - . "Regular Expression Cheat Sheet</a>\n<br><br>\n"; - - print "<p><font color=\"red\">NOTE:</font> The keyword search runs " - . "<tt>grep</tt> on the image.<br>\n" - . "A list of what will and " - . "what will not be found is available " - . "<a href=\"help/grep_lim.html\" target=\"_blank\">here</a>.<br>\n"; - - # Section for previous searches - if ($::LIVE == 0) { - my $srch_name = get_srch_fname(0); - if (-e $srch_name) { - print "<hr><h3>Previous Searches</h3>\n" . "<table width=600>\n"; - my $row_idx = 0; - - # Cycle through the files - for (my $srch_idx = 0;; $srch_idx++) { - - $srch_name = get_srch_fname($srch_idx); - - last unless (-e $srch_name); - - # Open the file to get the string and count - unless (open(SRCH, "$srch_name")) { - print "Error opening search file: $srch_name\n"; - return 1; - } - my $prev_str = ""; - my $prev_cnt = 0; - - while (<SRCH>) { - unless (/^(\d+)\|(.*?)?\|(.*)$/) { - print - "Error pasing header of search file: $srch_name\n"; - return 1; - } - $prev_cnt = $1; - $prev_str = $3; - if (length($prev_str) > 32) { - $prev_str = substr($prev_str, 0, 32); - $prev_str .= "..."; - } - - last; - } - close(SRCH); - - print "<tr>\n" if ($row_idx == 0); - - print " <td align=center width=150>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_KWSRCH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Kwsrch::RESULTS_FR\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . "<input type=\"hidden\" name=\"srchidx\" value=\"$srch_idx\">\n" - . Args::make_hidden(); - - print "<input type=\"SUBMIT\" value=\"".Print::html_encode($prev_str)." ($prev_cnt)\">" - . "<br></form>\n"; - - if ($row_idx == 3) { - print "</tr>\n"; - $row_idx = 0; - } - else { - $row_idx++; - } - } - print "</table>\n"; - } - } - - # Predefined expressions from search.pl - print "<hr><h3>Predefined Searches</h3>\n"; - print "<table width=600>\n"; - my $row_idx = 0; - my $r; - foreach $r (keys %Kwsrch::auto_srch) { - - $Kwsrch::auto_srch_reg{$r} = 0 - unless (defined $Kwsrch::auto_srch_reg{$r}); - $Kwsrch::auto_srch_csense{$r} = 1 - unless (defined $Kwsrch::auto_srch_csense{$r}); - - print "<tr>\n" if ($row_idx == 0); - - # @@@ Make a unicode option in predefined - - print " <td align=center width=150>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_KWSRCH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Kwsrch::RESULTS_FR\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . "<input type=\"hidden\" name=\"str\" value=\"$Kwsrch::auto_srch{$r}\">\n" - . "<input type=\"hidden\" name=\"ascii\" value=\"1\">\n" - . Args::make_hidden(); - - if ($Kwsrch::auto_srch_reg{$r} == 1) { - print - "<input type=\"hidden\" name=\"regexp\" value=\"$REG_EXP\">\n"; - } - if ($Kwsrch::auto_srch_csense{$r} == 0) { - print -"<input type=\"hidden\" name=\"srch_case\" value=\"$CASE_INSENS\">\n"; - } - print "<input type=\"SUBMIT\" value=\"$r\"><br></form>\n" . " </td>\n"; - - if ($row_idx == 3) { - print "</tr>\n"; - $row_idx = 0; - } - else { - $row_idx++; - } - } - print "</table>\n"; - - Print::print_html_footer(); - return 0; -} - -# MAIN WITH RESULTS -# Page that makes frame with the results on left and data units on right -sub results_fr { - my $vol = Args::get_vol('vol'); - - # A string was given for a new search - if (exists $Args::args{'str'}) { - Args::check_str(); - - Print::print_html_header_frameset( - "Search on $Caseman::vol2sname{$vol} for $Args::args{'str'}"); - - print "<frameset cols=\"35%,65%\">\n"; - - my $srch_case = ""; - $srch_case = "&srch_case=$Args::args{'srch_case'}" - if (exists $Args::args{'srch_case'}); - - my $regexp = ""; - $regexp = "®exp=$Args::args{'regexp'}" - if (exists $Args::args{'regexp'}); - - my $ascii = ""; - $ascii = "&ascii=$Args::args{'ascii'}" - if (exists $Args::args{'ascii'}); - - my $unicode = ""; - $unicode = "&unicode=$Args::args{'unicode'}" - if (exists $Args::args{'unicode'}); - - # Block List - print "<frame src=\"$::PROGNAME?" - . "mod=$::MOD_KWSRCH&view=$Kwsrch::RUN&" - . "$Args::baseargs$srch_case$regexp&str=$Args::enc_args{'str'}$ascii$unicode\">\n"; - } - elsif (exists $Args::args{'srchidx'}) { - Args::check_srchidx(); - - Print::print_html_header_frameset( -"Search on $Caseman::vol2sname{$vol} for Index $Args::args{'srchidx'}" - ); - - print "<frameset cols=\"35%,65%\">\n"; - - # Block List - print "<frame src=\"$::PROGNAME?" - . "mod=$::MOD_KWSRCH&view=$Kwsrch::LOAD&" - . "$Args::baseargs&srchidx=$Args::enc_args{'srchidx'}\">\n"; - } - - # Block Contents - print "<frame src=\"$::PROGNAME?mod=$::MOD_KWSRCH&view=$Kwsrch::BLANK&" - . "$Args::baseargs\" name=\"content\">\n" - . "</frameset>\n"; - - Print::print_html_footer_frameset(); - return 0; -} - -# Find an empty file to save the keyword searches to -sub find_srch_file { - my $vol = Args::get_vol('vol'); - - my $out_name = "$::host_dir" . "$::DATADIR/$Caseman::vol2sname{$vol}"; - my $i; - for ($i = 0; -e "${out_name}-${i}.srch"; $i++) { } - - return "${out_name}-${i}.srch"; -} - -# Pass the index -# return the full path of the file returned -sub get_srch_fname { - my $idx = shift; - my $vol = Args::get_vol('vol'); - return "$::host_dir" - . "$::DATADIR" - . "/$Caseman::vol2sname{$vol}-${idx}.srch"; -} - -sub load { - Args::check_srchidx(); - - Print::print_html_header(""); - - if ($::LIVE == 1) { - print "Searches cannot be loaded during live analysis<br>\n"; - return 1; - } - - my $srch_name = get_srch_fname($Args::args{'srchidx'}); - - print "<b><a href=\"$::PROGNAME?mod=$::MOD_KWSRCH&view=$Kwsrch::ENTER&" - . "$Args::baseargs\" " - . "target=\"_parent\">New Search</a></b>\n<p>"; - - print_srch_results($srch_name); - - Print::print_html_footer(); - return 0; -} - -# performs actual search, saves hits to file, and calls method to print -sub run { - Args::check_str(); - - Print::print_html_header(""); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $orig_str = Args::get_str(); - my $grep_str = $orig_str; # we will escape some values in the grep ver - - # Check for a search string - if ($orig_str eq "") { - print "You must enter a string value to search<br>\n"; - print "<b><a href=\"$::PROGNAME?mod=$::MOD_KWSRCH&view=$Kwsrch::ENTER&" - . "$Args::baseargs\" target=\"_parent\">New Search</a></b>\n<p>"; - return 1; - } - - my $log = ""; # Log entry string - - my $ascii = 0; - my $unicode = 0; - - if ((exists $Args::args{'ascii'}) && ($Args::args{'ascii'} == 1)) { - $ascii = 1; - $log .= "ASCII, "; - } - if ((exists $Args::args{'unicode'}) && ($Args::args{'unicode'} == 1)) { - $unicode = 1; - $log .= "Unicode, "; - } - - if (($ascii == 0) && ($unicode == 0)) { - print "You must choose either ASCII or Unicode to search<br>\n"; - print "<b><a href=\"$::PROGNAME?mod=$::MOD_KWSRCH&view=$Kwsrch::ENTER&" - . "$Args::baseargs\" target=\"_parent\">New Search</a></b>\n<p>"; - return 1; - } - - my $grep_flag = ""; # Flags to pass to grep - - # Check if search is case insensitive - my $case = 0; - if ( (exists $Args::args{'srch_case'}) - && ($Args::args{'srch_case'} == $CASE_INSENS)) - { - $grep_flag = "-i"; - $case = 1; - $log .= "Case Insensitive "; - } - - # Check if search is a regular expression - my $regexp = 0; - if ((exists $Args::args{'regexp'}) && ($Args::args{'regexp'} == $REG_EXP)) { - $grep_flag .= " -E"; - $regexp = 1; - $log .= "Regular Expression "; - } - - # if not a reg-exp, we need to escape some special values that - # 'grep' will misinterpret - else { - $grep_str =~ s/\\/\\\\/g; # \ - $grep_str =~ s/\./\\\./g; # . - $grep_str =~ s/\[/\\\[/g; # [ - $grep_str =~ s/\^/\\\^/g; # ^ - $grep_str =~ s/\$/\\\$/g; # $ - $grep_str =~ s/\*/\\\*/g; # * - # We need to add ' to end begin and end of the search as well - if ($grep_str =~ /\'/) { - $grep_str =~ s/\'/\\\'/g; # ' - $grep_str = "'$grep_str'"; - } - $grep_str =~ s/^\-/\\\-/; # starting with - (mistakes for an arg) - } - - Print::log_host_inv( - "$Caseman::vol2sname{$vol}: ${log}search for $grep_str"); - - # Get the addressable unit of image - my $bs = Args::get_unitsize(); - - # $norm_str is normalized to find the "hit" in the output - my $norm_str = $orig_str; - - # make this lowercase if we are doing case insens - $norm_str =~ tr/[A-Z]/[a-z]/ if ($case == 1); - - my $norm_str_len = length($norm_str); - - # array to pass to printing method - my @results; - - my $name_uni = ""; - my $name_asc = ""; - - # round 0 is for ASCII and 1 is for Unicode - for (my $i = 0; $i < 2; $i++) { - - next if (($i == 0) && ($ascii == 0)); - next if (($i == 1) && ($unicode == 0)); - - @results = (); - - local *OUT; - - my $hit_cnt = 0; - $SIG{ALRM} = sub { - if (($hit_cnt++ % 5) == 0) { - print "+"; - } - else { - print "-"; - } - alarm(5); - }; - - alarm(5); - - if ($i == 0) { - print "<b>Searching for ASCII</b>: "; - } - else { - print "<b>Searching for Unicode</b>: "; - } - - # if the string is less than 4 chars, then it will not be in the - # strings file so it will be searched for the slow way - if (length($orig_str) < 4) { - my $ltmp = length($orig_str); - - if ($i == 0) { - if ( (($ftype eq "raw") || ($ftype eq "swap")) - && ($Caseman::vol2end{$vol} != 0)) - { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " - . $Caseman::vol2start{$vol} . "-" - . $Caseman::vol2end{$vol} - . " | '$::TSKDIR/srch_strings' -a -t d -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - } - - else { - if ( (($ftype eq "raw") || ($ftype eq "swap")) - && ($Caseman::vol2end{$vol} != 0)) - { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " - . $Caseman::vol2start{$vol} . "-" - . $Caseman::vol2end{$vol} - . " | '$::TSKDIR/srch_strings' -a -t d -e l -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -e l -$ltmp | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - } - } - - # Use the strings file if it exists - elsif (($i == 0) && (defined $Caseman::vol2str{$vol})) { - my $str_vol = $Caseman::vol2path{$Caseman::vol2str{$vol}}; - Exec::exec_pipe(*OUT, - "'$::GREP_EXE' $grep_flag '$grep_str' $str_vol"); - } - elsif (($i == 1) && (defined $Caseman::vol2uni{$vol})) { - my $str_vol = $Caseman::vol2path{$Caseman::vol2uni{$vol}}; - Exec::exec_pipe(*OUT, - "'$::GREP_EXE' $grep_flag '$grep_str' $str_vol"); - } - - # Run strings on the image first and then grep that - else { - if ($i == 0) { - if ( (($ftype eq "raw") || ($ftype eq "swap")) - && ($Caseman::vol2end{$vol} != 0)) - { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " - . $Caseman::vol2start{$vol} . "-" - . $Caseman::vol2end{$vol} - . " | '$::TSKDIR/srch_strings' -a -t d | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - } - else { - if ( (($ftype eq "raw") || ($ftype eq "swap")) - && ($Caseman::vol2end{$vol} != 0)) - { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/blkls' -e -f $ftype -i $imgtype $img " - . $Caseman::vol2start{$vol} . "-" - . $Caseman::vol2end{$vol} - . " | '$::TSKDIR/srch_strings' -a -t d -e l | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/blkls' -e -f $ftype -o $offset -i $imgtype $img | '$::TSKDIR/srch_strings' -a -t d -e l | '$::GREP_EXE' $grep_flag '$grep_str'" - ); - } - } - } - - alarm(0); - $SIG{ALRM} = 'DEFAULT'; - - # Cycle through the results and put them in an array - while ($_ = Exec::read_pipe_line(*OUT)) { - - # Parse out the byte offset and hit string - if (/^\s*(\d+)\s+(.+)$/) { - my $off = $1; - my $hit_str_orig = $2; - my $idx = 0; - - # Make a copy that we can modify & play with - my $hit_str = $hit_str_orig; - $hit_str =~ tr/[A-Z]/[a-z]/ if ($case == 1); - - # How long was the string that we hit? - my $hit_str_len = length($hit_str); - - # I'm not sure how to find a grep re in the hit yet, so - # for now we do not get the exact offset - if ($regexp) { - my $b = int($off / $bs); - my $o = int($off % $bs); - - # $hit =~ s/\n//g; - push @results, "${b}|${o}|"; - next; - } - - # There could be more than one keyword in the string - # so cycle through all of them - my $psize = scalar(@results); - while (($idx = index($hit_str, $norm_str, $idx)) > -1) { - - # The summary of the hit starts 5 chars before it - my $sum_min = $idx - 5; - $sum_min = 0 if ($sum_min < 0); - - # Goto 5 after, if there is still space - my $sum_max = $idx + $norm_str_len + 5; - $sum_max = $hit_str_len if ($sum_max > $hit_str_len); - - my $sum_hit = - substr($hit_str_orig, $sum_min, $sum_max - $sum_min); - - # remove new lines - $sum_hit =~ s/\n/ /g; - - # The actual offset for Unicode is 2 bytes per char - my $tmpidx = $idx; - $tmpidx *= 2 - if ($i == 1); - - my $b = int(($off + $tmpidx) / $bs); - my $o = int(($off + $tmpidx) % $bs); - - push @results, "${b}|${o}|$sum_hit"; - - # advance index to find next hit - $idx++; - } - - # If we did not find a term, then just print what - # was found-this occurs bc index does not find it - # sometimes. - if ($psize == scalar(@results)) { - - my $b = int($off / $bs); - my $o = int($off % $bs); - - # $hit =~ s/\n//g; - push @results, "${b}|${o}|"; - next; - } - } - - # A negative offset is common on FreeBSD with large images - elsif (/^\s*(\-\d+):?\s*(.+)$/) { - print "ERROR: Negative byte offset ($1) Your version of " - . "strings likely does not support large files: $2<br>\n"; - } - else { - print "Error parsing grep result: $_<br>\n"; - } - } - close(OUT); - - print " <b>Done</b><br>"; - my $cnt = scalar(@results); - - my $srch_name = ""; - if ($::LIVE == 0) { - print "<b>Saving</b>: "; - - # Find a file to save the results to - $srch_name = find_srch_file(); - unless (open(IDX, ">$srch_name")) { - print "Error opening $srch_name\n"; - return (1); - } - - # Print the header - if ($i == 0) { - print IDX "$cnt|${grep_flag}|${orig_str}|ascii\n"; - $name_asc = $srch_name; - } - else { - print IDX "$cnt|${grep_flag}|${orig_str}|unicode\n"; - $name_uni = $srch_name; - } - - for (my $a = 0; $a < $cnt; $a++) { - print IDX "$results[$a]\n"; - } - close(IDX); - print " <b>Done</b><br>\n"; - } - if ($i == 0) { - print "$cnt hits"; - print "- <a href=\"#ascii\">link to results</a>" if ($cnt > 0); - print "<br>\n"; - } - else { - print "$cnt hits"; - print "- <a href=\"#unicode\">link to results</a>" if ($cnt > 0); - print "<br>\n"; - } - print "<hr>\n"; - } - - print "<b><a href=\"$::PROGNAME?mod=$::MOD_KWSRCH&view=$Kwsrch::ENTER&" - . "$Args::baseargs\" " - . "target=\"_parent\">New Search</a></b>\n<p>"; - - if ($::LIVE == 0) { - if ($ascii == 1) { - print_srch_results($name_asc); - } - - if ($unicode == 1) { - print_srch_results($name_uni); - } - } - - Print::print_html_footer(); - return 0; -} - -# Args are search string, grep flags, and array of hits -sub print_srch_results { - - if (scalar(@_) != 1) { - print "Missing Args for print_srch_results()\n"; - return 1; - } - - my $srch_name = shift; - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - - my $addr_str = $Fs::addr_unit{$ftype}; - - unless (open(SRCH, "$srch_name")) { - print "Error opening search file: $srch_name\n"; - return 1; - } - - my @results; - my $grep_str = ""; - my $grep_flag = ""; - my $cnt = 0; - my $type = 0; # ASCII iis 0 and Unicode is 1 - - my $prev = -1; - - while (<SRCH>) { - - # The first line is a header - if ($. == 1) { - if (/^(\d+)\|(.*?)?\|(.*)$/) { - $cnt = $1; - $grep_flag = $2; - $grep_str = $3; - $type = 0; - } - else { - print "Error pasing header of search file: $srch_name\n"; - close(SRCH); - return 1; - } - - if ($grep_str =~ /^(.*?)\|unicode$/) { - $grep_str = $1; - $type = 1; - } - elsif ($grep_str =~ /^(.*?)\|ascii$/) { - $grep_str = $1; - } - - my $grep_str_html = Print::html_encode($grep_str); - print "<hr>\n"; - if ($type == 0) { - print "<a name=\"ascii\">\n"; - } - else { - print "<a name=\"unicode\">\n"; - } - - if ($cnt == 0) { - print "<b><tt>$grep_str_html</tt> was not found</b><br>\n"; - } - elsif ($cnt == 1) { - print -"<b>1 occurrence of <tt>$grep_str_html</tt> was found</b><br>\n"; - } - else { - print -"<b>$cnt occurrences of <tt>$grep_str_html</tt> were found</b><br>\n"; - } - - print "Search Options:<br>\n"; - if ($type == 0) { - print "  ASCII<br>\n"; - } - else { - print "  Unicode<br>\n"; - } - - if ($grep_flag =~ /\-i/) { - print "  Case Insensitive<br>\n"; - } - else { - print "  Case Sensitive<br>\n"; - } - if ($grep_flag =~ /\-E/) { - print "  Regular Expression<br>\n"; - } - - print "<hr>\n"; - - if ($cnt > 1000) { - print "There were more than <U>1000</U> hits.<br>\n"; - print "Please revise the search to a managable amount.\n"; - print - "<p>The $cnt hits can be found in: <tt>$srch_name</tt><br>\n"; - close(SRCH); - return 0; - } - - next; - } - - unless (/^(\d+)\|(\d+)\|(.*)?$/) { - print "Error parsing results: $_\n"; - close(SRCH); - return 1; - } - - my $blk = $1; - my $off = $2; - my $str = $3; - - if ($blk != $prev) { - my $url = -"$::PROGNAME?mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&$Args::baseargs&block=$blk"; - - print "<br>\n$addr_str $blk (<a href=\"$url&sort=$Data::SORT_HEX\" " - . "target=content>Hex</a> - " - . "<a href=\"$url&sort=$Data::SORT_ASC\" target=content>" - . "Ascii</a>"; - - print -" - <a href=\"$::PROGNAME?$Args::baseargs&mod=$::MOD_DATA&view=$Data::CONT_MENU_FR&" - . "mnt=$Args::enc_args{'mnt'}&vol=$Caseman::mod2vol{$vol}&" - . "btype=$Data::ADDR_BLKLS&block=$blk\" target=content>Original</a>" - if ( ($ftype eq 'blkls') - && (exists $Caseman::mod2vol{$vol})); - - print ")<br>"; - $prev = $blk; - } - - my $occ = $. - 1; - if ($str ne "") { - $str = Print::html_encode($str); - print "$occ: $off (<tt>$str</tt>)<br>\n"; - } - else { - print "$occ: $off<br>\n"; - } - } - - close(SRCH); - return 0; -} - -# Blank Page -sub blank { - Print::print_html_header(""); - print "<!-- This Page Intentionally Left Blank -->\n"; - Print::print_html_footer(); - return 0; -} - -1; diff --git a/lib/Main.pm b/lib/Main.pm deleted file mode 100644 index 88c39f67a7..0000000000 --- a/lib/Main.pm +++ /dev/null @@ -1,357 +0,0 @@ -# -# Main.pm -# Autopsy Forensic Browser -# -# This file requires The Sleuth Kit -# www.sleuthkit.org -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. -# - -use lib './'; -use strict; - -use Appsort; -use Appview; -use Args; -use Caseman; -use Data; -use Exec; -use File; -use Filesystem; -use Frame; -use Fs; -use Hash; -use Kwsrch; -use Meta; -use Notes; -use Print; -use Timeline; -use Vs; - -require 'conf.pl'; -require 'define.pl'; - -# Get rid of insecure settings -$ENV{PATH} = ""; -delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; - -# Formats for regular expressions -# Year.Mon.Day Hr:Min:Sec (TZ) -$::REG_DAY = '\d\d\d\d\-\d\d\-\d\d'; -$::REG_TIME = '\d\d:\d\d:\d\d'; -$::REG_ZONE_ARGS = '[\w\+\-\/\_]+'; -$::REG_ZONE2 = '\([\w\+\- ]*\)'; -$::REG_DATE = "$::REG_DAY" . '\s+' . "$::REG_TIME" . '\s+' . "$::REG_ZONE2"; -$::REG_FTYPE = '[\w\-]+'; -$::REG_SKEW = '[\+\-]?\d+'; -$::REG_MTYPE = '[\?bcdflprsvw-]'; # Type according to meta data - -$::REG_FILE = '[\w\-\_\.]+'; -$::REG_CASE = $::REG_FILE; -$::REG_HOST = '[\w\-\_\.]+'; -$::REG_INVESTIG = '[\w]+'; - -$::REG_IMG = "$::REG_FILE" . '/' . "$::REG_FILE"; -$::REG_IMG_PATH = '/[\w\-\_\.\/]+'; -$::REG_IMG_PATH_WILD = '/[\w\-\_\.\/]+\*?'; -$::REG_IMG_CONFIG = '[\w\-\_\.\/ ]+'; -$::REG_FNAME = $::REG_FILE; -$::REG_MNT = '[\w\-\_\.\/\:\\\\]+'; -$::REG_SEQ_FILE = '[\w\s\-\_\.\/\:\\\\]+'; -$::REG_HASHDB = '[\w\-\_\.\,\/]+'; -$::REG_IMGTYPE = '[\w\,]+'; -$::REG_INAME = '[\w]+'; -$::REG_VNAME = '[\w]+'; - -$::REG_META = '[\d-]+'; -$::REG_MD5 = '[0-9a-fA-F]{32,32}'; - -$::HELP_URL = "help/index.html"; - -# host_dir and case_dir will end with a '/' -$::host_dir = ""; -$::case_dir = ""; - -################## NEW STUFF ########################## -# MODULES - -# If the values of these are changed, or if new modules are added, -# Then the below pseudo-binary sort algorithm must be changed as well -$::MOD_CASEMAN = 0; -$::MOD_FRAME = 1; -$::MOD_FILE = 2; -$::MOD_META = 3; -$::MOD_KWSRCH = 4; -$::MOD_DATA = 5; -$::MOD_TL = 6; -$::MOD_FS = 7; -$::MOD_APPSORT = 8; -$::MOD_NOTES = 9; -$::MOD_HASH = 10; -$::MOD_APPVIEW = 11; - -# Main Menu -# -# Display the title page -sub welcome { - Print::print_html_header_javascript("Autopsy Forensic Browser"); - - print "<center>\n"; - - # This problem has not been seen with the 1 second delay - if ((0) && ($] >= 5.008)) { - print -"<p><font color=\"red\">Warning: You are using Perl v5.8.</font><br>\n" - . " Some buffer problems have been reported with Autopsy and Perl 5.8 " - . "where output is not shown.<br>\n" - . "Perl 5.6 should be used if available.\n" - . "If data is missing, reload the page<br><hr>\n"; - } - - print <<EOF; -<table cellspacing=0 cellpadding=2 width=600 height=350 border=0> - -<tr> - <td colspan=\"3\" align=\"center\" valign=\"MIDDLE\"> - <b>Autopsy Forensic Browser $::VER</b> - </td> -</tr> -<tr> - <td colspan=\"3\"> </td> -</tr> -<tr> - <td colspan=\"3\" align=\"center\" valign=\"MIDDLE\"> - <a href=\"./about\"> - <img src=\"pict/logo.jpg\" border=0 alt="Logo"> - </a> - </td> -</tr> -<tr> - <td colspan=\"3\"> </td> -</tr> -<tr> - <td colspan=\"3\" align=\"center\" valign=\"MIDDLE\"> - <a href="http://www.sleuthkit.org/autopsy/"> - <tt>http://www.sleuthkit.org/autopsy/</tt> - </a> - </td> -</tr> -<tr><td colspan=3> </td></tr> -<tr> - <td align=center width=200 valign=\"MIDDLE\"> - <a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::CASE_OPEN\"> - <img src=\"pict/menu_b_copen.jpg\" alt=\"Open Case\" width=176 height=20 border=0> - </a> - </td> - <td align=center width=200 valign=\"MIDDLE\"> - <a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::CASE_NEW\"> - <img src=\"pict/menu_b_cnew.jpg\" alt=\"New Case\" width=176 height=20 border=0> - </a> - </td> - <td align=center width=200 valign=\"MIDDLE\"> - <a href=\"$::HELP_URL\" target=\"_blank\"> - <img src=\"pict/menu_b_help.jpg\" alt=\"Help\" width=167 height=20 border=0> - </a> - </td> -</tr> -</table> - -EOF - - Print::print_html_footer_javascript(); - return 0; -} - -sub get_tskver { - local *OUT; - Exec::exec_pipe(*OUT, "'$::TSKDIR/fls' -V"); - - my $ver = Exec::read_pipe_line(*OUT); - $ver = $1 if ($ver =~ /^The Sleuth Kit ver (.*)$/); - close(OUT); - - return $ver; -} - -# This function is called by the code in the 'autopy' file. -# This will check for the basic module arguments and then host -# and case accordingly. The main function of each of the modules -# is called from here. Each of the modules will have to take care -# of the detailed argument checking. - -sub main { - - # Parse arguments - my $lcl_args = shift; - Args::parse_args($lcl_args); - - # When autopsy is first run, no mod or arguments are given. - unless (exists $Args::args{'mod'}) { - - # if we are not in live analysis mode, display the usual screen - if ($::LIVE == 0) { - return welcome(); - } - else { - - # If we are in live analysis mode, open up the window to select - # and image and supply basic host and case values. - $Args::args{'mod'} = $Args::enc_args{'mod'} = $::MOD_CASEMAN; - $Args::args{'view'} = $Args::enc_args{'view'} = $Caseman::VOL_OPEN; - $Args::args{'case'} = $Args::enc_args{'case'} = "live"; - $Args::args{'host'} = $Args::enc_args{'host'} = "local"; - $Args::args{'inv'} = $Args::enc_args{'inv'} = "unknown"; - } - } - - Args::check_mod(); - my $module = Args::get_mod(); - - Args::make_baseargs(); - - # For live analysis, we need to change the regular expression - # for images because it can be a full path (to /dev/xxxxxxx) - $::REG_IMG = '/[\w\-\_\.\/]+' - if ($::LIVE == 1); - - # The Case Management module is handled seperately because - # it may not have the host and case values - if ($module == $::MOD_CASEMAN) { - return Caseman::main(); - } - - # Check the minimum arguments - Args::check_case(); - Args::check_host(); - - # Set the case and host variables - if ($::LIVE == 0) { - $::case_dir = "$::LOCKDIR/" . Args::get_case() . "/"; - $::case_dir =~ s/\/\//\//g; - $::host_dir = "$::case_dir" . Args::get_host() . "/"; - $::host_dir =~ s/\/\//\//g; - } - else { - $::host_dir = ""; - $::case_dir = ""; - } - Caseman::read_host_config(); - - # This is a partial binary sort method to reduce the number of checks - - # 0 < mod < 6 - if ($module < $::MOD_TL) { - - # 0 < mod < 4 - if ($module < $::MOD_KWSRCH) { - - # mod == 1 - if ($module == $::MOD_FRAME) { - return Frame::main(); - } - - # mod == 2 - elsif ($module == $::MOD_FILE) { - return File::main(); - } - - # mod == 3 - elsif ($module == $::MOD_META) { - return Meta::main(); - } - } - - # 4 <= mod < 6 - else { - - # mod == 4 - if ($module == $::MOD_KWSRCH) { - return Kwsrch::main(); - } - - # mod == 5 - elsif ($module == $::MOD_DATA) { - return Data::main(); - } - } - } - - # 6 <= mod - else { - - # 6 <= mod < 9 - if ($module < $::MOD_NOTES) { - - # mod == 6 - if ($module == $::MOD_TL) { - return Timeline::main(); - } - - # mod == 7 - elsif ($module == $::MOD_FS) { - return Filesystem::main(); - } - - # mod == 8 - elsif ($module == $::MOD_APPSORT) { - return Appsort::main(); - } - } - - # 9 <= mod - else { - - # mod == 9 - if ($module == $::MOD_NOTES) { - return Notes::main(); - } - - # mod == 10 - elsif ($module == $::MOD_HASH) { - return Hash::main(); - } - - # mod == 11 - elsif ($module == $::MOD_APPVIEW) { - return Appview::main(); - } - - # New modules can be added here - - } - } - Print::print_check_err("Invalid Module"); -} - -1; diff --git a/lib/Meta.pm b/lib/Meta.pm deleted file mode 100644 index a0728c06b9..0000000000 --- a/lib/Meta.pm +++ /dev/null @@ -1,789 +0,0 @@ -# -# Metadata mode -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -# Updated 1/13 - -package Meta; - -$Meta::FRAME = 0; -$Meta::ENTER = 1; -$Meta::STATS = 2; -$Meta::EXPORT = 3; -$Meta::FFIND = 4; -$Meta::LIST = 5; -$Meta::REPORT = 6; -$Meta::BLANK = 7; - -sub main { - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $Meta::FRAME - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - # Check Basic Args - Args::check_vol('vol'); - - # These windows don't need the meta data address - if ($view == $Meta::FRAME) { - return frame(); - } - elsif ($view == $Meta::ENTER) { - return enter(); - } - elsif ($view == $Meta::LIST) { - return list(); - } - elsif ($view == $Meta::BLANK) { - return blank(); - } - - # These windows do need the meta data address - Args::check_meta('meta'); - if ($view == $Meta::STATS) { - return stats(); - } - elsif ($view == $Meta::FFIND) { - return findfile(); - } - - Args::check_recmode(); - if ($view == $Meta::EXPORT) { - return export(); - } - elsif ($view == $Meta::REPORT) { - return report(); - } - else { - Print::print_check_err("Invalid Meta View"); - } - -} - -# Print the two frames -sub frame { - - my $vol = Args::get_vol('vol'); - - Print::print_html_header_frameset( - "Meta Data Browse on $Caseman::vol2sname{$vol}"); - print "<frameset cols=\"20%,80%\">\n"; - - # Print the frame where an addres can be entered and a frame for the - # contents - if (exists $Args::enc_args{'meta'}) { - print -"<frame src=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::ENTER&$Args::baseargs" - . "&meta=$Args::enc_args{'meta'}\">\n" - . "<frame src=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::STATS&" - . "meta=$Args::enc_args{'meta'}&$Args::baseargs\" " - . "name=\"content\">\n</frameset>\n"; - } - else { - print -"<frame src=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::ENTER&$Args::baseargs\">\n" - . "<frame src=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::BLANK&$Args::baseargs\" " - . "name=\"content\">\n</frameset>\n"; - } - - Print::print_html_footer_frameset(); - return 0; -} - -# Generate the frame to enter the data into -sub enter { - Print::print_html_header(""); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - - # Address - print "<form action=\"$::PROGNAME\" method=\"get\" target=\"content\">\n" - . "<b>$Fs::meta_str{$ftype} Number:</b><br>    " - . "<input type=\"text\" name=\"meta\" size=12 maxlength=12"; - - print " value=\"$Args::enc_args{'meta'}\"" if exists($Args::args{'meta'}); - - print ">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_META\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Meta::STATS\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . Args::make_hidden() - . - - # View Button - "<p><input type=\"image\" src=\"pict/but_view.jpg\" " - . "width=45 height=22 alt=\"View\" border=\"0\"></form>\n"; - - # Allocation List - print "<hr><p>" - . "<a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::LIST&$Args::baseargs\" target=\"content\">" - . "<img src=\"pict/but_alloc_list.jpg\" border=\"0\" " - . "width=113 height=20 alt=\"Allocation List\">" - . "</a>\n"; - - Print::print_html_footer(); - return 0; -} - -# Display the contents of meta -sub stats { - Print::print_html_header(""); - - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Displaying details of $Fs::meta_str{$ftype} $meta" - ); - - my $meta_int = $meta; - $meta_int = $1 if ($meta =~ /^(\d+)-\d+(-\d)?/); - - my $prev = $meta_int - 1; - my $next = $meta_int + 1; - - # We need to get the allocation status of this structure - my $recmode = $File::REC_NO; - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ils' -f $ftype -e -o $offset -i $imgtype $img $meta_int"); - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - next unless ($_ =~ /^$meta_int/); - if ($_ =~ /^$meta_int\|f/) { - $recmode = $File::REC_YES; - } - elsif ($_ =~ /^$meta_int\|a/) { - $recmode = $File::REC_NO; - } - else { - Print::print_err("Error parsing ils output: $_"); - } - } - close(OUT); - - print "<center>\n"; - print -"<a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::STATS&$Args::baseargs&meta=$prev\">" - . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " - . "width=\"89\" height=20 border=\"0\"></a>\n" - unless ($prev < $Fs::first_meta{$ftype}); - - print -"<a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::STATS&$Args::baseargs&meta=$next\">" - . "<img src=\"pict/but_next.jpg\" alt=\"next\" " - . "width=\"89\" height=20 border=\"0\"></a>\n<br>"; - - # Report - print "<table cellspacing=\"0\" cellpadding=\"2\">\n<tr>" - . "<td><a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::REPORT" - . "&$Args::baseargs&meta=$meta&recmode=$recmode\"" - . " target=\"_blank\">" - . "<img src=\"pict/but_report.jpg\" alt=\"report\" " - . "width=88 height=20 border=\"0\">" - . "</a></td>\n"; - - # View (File Mode) - print "<td><a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR" - . "&$Args::baseargs&meta=$meta&recmode=$recmode" - . "&dir=$vol-meta-$meta\" target=\"_blank\">" - . "<img src=\"pict/but_viewcont.jpg\" alt=\"view contents\" " - . "width=123 height=20 border=\"0\">" - . "</a></td>\n"; - - # Export - print "<td><a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::EXPORT" - . "&$Args::baseargs&meta=$meta&recmode=$recmode\">" - . "<img src=\"pict/but_export.jpg\" alt=\"export\" " - . "width=123 height=20 border=\"0\">" - . "</a></td>"; - - # Notes - print "<td><a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::ENTER_FILE" - . "&$Args::baseargs&meta=$meta&\" " - . "target=\"_blank\">" - . "<img src=\"pict/but_addnote.jpg\" alt=\"Add Note\" " - . "width=\"89\" height=20 border=\"0\">" - . "</a></td>" - if ($::USE_NOTES == 1); - - print "</tr></table>\n</center>\n"; - - my $tmpr = $Caseman::vol2mnt{$vol}; - - if ($ftype =~ /fat/) { - print -"<a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::FFIND&$Args::baseargs&" - . "meta=$meta\" target=\"_blank\">Search for File Name</a><br><br>"; - } - else { - - print "<b>Pointed to by file:</b><br>\n"; - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); - my $cnt = 0; - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - if (/^(\*)\s+\/*(.*)$/) { - Print::print_output("<tt><font color=\"$::DEL_COLOR[0]\">" - . Print::html_encode($tmpr . $2) - . "</font></tt> (deleted)<br><br>\n"); - } - elsif (/^\/(.*)$/) { - Print::print_output("<tt>" - . Print::html_encode($tmpr . $1) - . "</tt><br><br>\n"); - } - else { - Print::print_output(Print::html_encode($_) . "<br><br>\n"); - } - $cnt++; - } - close(OUT); - if ($cnt == 0) { - print "<br>Invalid $Fs::meta_str{$ftype} value<br><br>\n"; - return; - } - } - - if ($recmode == $File::REC_YES) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - my $file_type = Exec::read_pipe_line(*OUT); - close(OUT); - - $file_type = "Error getting file type" - if ((!defined $file_type) || ($file_type eq "")); - - if ($recmode == $File::REC_YES) { - print "<b>File Type (Recovered):</b><br>$file_type<br>\n"; - } - else { - print "<b>File Type:</b><br>$file_type<br><br>\n"; - } - - # MD5 Value - if ($recmode == $File::REC_YES) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" - ); - } - - my $md5out = Exec::read_pipe_line(*OUT); - close(OUT); - - $md5out = "Error getting MD5" - if ((!defined $md5out) || ($md5out eq "")); - - chomp $md5out; - if ($recmode == $File::REC_YES) { - print "<b>MD5 of recovered content:</b><br><tt>$md5out</tt><br><br>\n"; - } - else { - print "<b>MD5 of content:</b><br><tt>$md5out</tt><br><br>\n"; - } - - # Hash Database Lookups - if ( - ( - ($::NSRLDB ne "") - || ($Caseman::alert_db ne "") - || ($Caseman::exclude_db ne "") - ) - && ($md5out =~ /^$::REG_MD5$/o) - ) - { - - print "<form action=\"$::PROGNAME\" method=\"get\" target=\"_blank\">\n" - . Args::make_hidden() - . "<input type=\"hidden\" name=\"md5\" value=\"$md5out\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_HASH\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Hash::DB_LOOKUP\">\n" - . "<table cellpadding=\"2\" cellspacing=\"8\"><tr>\n"; - - if ($::NSRLDB ne "") { - print "<td align=\"left\">" - . "<input type=\"checkbox\" name=\"hash_nsrl\" value=\"1\" CHECKED>" - . "NSRL</td>\n"; - } - if ($Caseman::alert_db ne "") { - print "<td align=\"left\">" - . "<input type=\"checkbox\" name=\"hash_alert\" value=\"1\" CHECKED>" - . "Alert Database</td>\n"; - } - if ($Caseman::exclude_db ne "") { - print "<td align=\"left\">" - . "<input type=\"checkbox\" name=\"hash_exclude\" value=\"1\" CHECKED>" - . "Exclude Database</td>\n"; - } - print "<td align=\"left\">" - . "<input type=\"image\" src=\"pict/but_lookup.jpg\" " - . "width=116 height=20 alt=\"Ok\" border=\"0\">" - . "</td></tr></table>\n</form>\n"; - } - - # SHA-1 Value - if ($::SHA1_EXE ne "") { - if ($recmode == $File::REC_YES) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" - ); - } - - my $sha1out = Exec::read_pipe_line(*OUT); - close(OUT); - - $sha1out = "Error getting SHA-1" - if ((!defined $sha1out) || ($sha1out eq "")); - - chomp $sha1out; - if ($recmode == $File::REC_YES) { - print -"<b>SHA-1 of recovered content:</b><br><tt>$sha1out</tt><br><br>\n"; - } - else { - print "<b>SHA-1 of content:</b><br><tt>$sha1out</tt><br><br>\n"; - } - } - - # istat output - print "<b>Details:</b><br><br>\n"; - my $mode = 0; # set to 1 when showing blocks - my $force = 0; # set to 1 if size of meta is 0 - - my @output; - if (exists($Args::args{'force'})) { - my $f = Args::get_force(); - Exec::exec_pipe(*OUT, -"'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -B $f -o $offset -i $imgtype $img $meta" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" - ); - } - while ($_ = Exec::read_pipe_line(*OUT)) { - if ($mode == 1) { - if (/^Indirect Blocks/) { - print "$_<br>\n"; - next; - } - elsif (/^Recover/) { - print "$_<br>\n"; - next; - } - elsif (/^Type: (\S+) \((\d+\-\d+)\) (.*)$/) { - print "$1 (" - . "<a href=\"$::PROGNAME?mod=$::MOD_FILE&view=$File::CONT_FR&$Args::baseargs" - . "&meta=$meta_int-$2&dir=$vol-meta-$meta_int-$2\" " - . "target=\"_blank\">$2</a>) $3<br>\n"; - next; - } - - my $blk; - foreach $blk (split(/ /, $_)) { - if ($blk =~ /^\d+$/) { - print -"<a href=\"$::PROGNAME?mod=$::MOD_FRAME&submod=$::MOD_DATA&" - . "$Args::baseargs&block=$blk\" target=\"_top\">$blk</a> "; - } - else { - print "$blk "; - } - } - print "<br>\n"; - } - else { - if (/^Not Allocated$/) { - print "<font color=\"$::DEL_COLOR[0]\">$_</font><br>\n"; - } - else { - print "$_<br>\n"; - } - $mode = 1 if (/^Direct Blocks|^Sectors/); - $mode = 1 if (/^Attributes:/); # HFS gets messed up without ":" - $mode = 1 if (/^Data Fork Blocks:/); - - if ((/^size: (\d+)/) && ($1 == 0)) { - $force = 1; - } - } - } - close(OUT); - - # display a text box to force X number of blocks to be displayed - if ($force == 1) { - print "<form action=\"$::PROGNAME\" method=\"get\">\n" - . Args::make_hidden() - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . "<input type=\"hidden\" name=\"meta\" value=\"$meta\">\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_META\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Meta::STATS\">\n"; - - print -"Enter number of $Fs::addr_unit{$ftype}s to display: <input type=\"text\" " - . "value=5 name=\"force\" size=\"3\">\n"; - - print "<input type=\"image\" src=\"pict/but_force.jpg\" " - . "width=53 height=20 alt=\"Force\" border=\"0\"> (because the size is 0)\n</form>\n"; - } - - Print::print_html_footer(); - return 0; -} - -sub findfile { - - Print::print_html_header("Find File"); - - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $tmpr = $Caseman::vol2mnt{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - print "<b>Pointed to by file:</b><br>\n"; - - local *OUT; - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - if (/(\*)\s+\/*(.*)/) { - Print::print_output("<tt><font color=\"$::DEL_COLOR[0]\">" - . Print::html_encode($tmpr . $2) - . "</font></tt> (deleted)<br>\n"); - } - elsif (/^\/(.*)$/) { - Print::print_output( - "<tt>" . Print::html_encode($tmpr . $1) . "</tt><br>\n"); - } - else { - Print::print_output(Print::html_encode($_) . "<br>\n"); - } - } - close(OUT); - - Print::print_html_footer(); - return 0; -} - -sub export { - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $recmode = Args::get_recmode(); - - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Saving contents of $Fs::meta_str{$ftype} $meta" - ); - - Print::print_oct_header("$vol" . "-meta" . "$meta" . ".raw"); - - local *OUT; - if ($recmode == $File::REC_YES) { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta"); - } - else { - Exec::exec_pipe(*OUT, - "'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta"); - } - - print "$_" while ($_ = Exec::read_pipe_data(*OUT, 512)); - close(OUT); - - Print::print_oct_footer(); -} - -sub report { - - my $meta = Args::get_meta('meta'); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - my $recmode = Args::get_recmode(); - - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: Generating report for $Fs::meta_str{$ftype} $meta" - ); - - Print::print_text_header("filename=$vol-meta$meta.txt"); - - print " Autopsy $Fs::meta_str{$ftype} Report\n\n" - . "-" x 70 . "\n" - . " GENERAL INFORMATION\n\n" - . "$Fs::meta_str{$ftype}: $Args::args{'meta'}\n"; - - print "Pointed to by file(s):\n"; - my $tmpr = $Caseman::vol2mnt{$vol}; - local *OUT; - - Exec::exec_pipe(*OUT, - "'$::TSKDIR/ffind' -f $ftype -a -o $offset -i $imgtype $img $meta"); - while ($_ = Exec::read_pipe_line(*OUT)) { - chop; - if (/^(\*)\s+\/*(.*)$/) { - Print::print_output( - " ${tmpr}${2} (deleted)\n"); - } - elsif (/^\/(.*)$/) { - Print::print_output(" ${tmpr}${1}\n"); - } - else { - Print::print_output(" $_\n"); - } - } - close(OUT); - - Exec::exec_pipe(*OUT, -"'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta | '$::MD5_EXE'" - ); - my $md5 = Exec::read_pipe_line(*OUT); - close(OUT); - - $md5 = "Error getting MD5 Value" - if ((!defined $md5) || ($md5 eq "")); - - chop $md5; - print "MD5 of istat output: $md5\n"; - - if ($::SHA1_EXE ne "") { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta | '$::SHA1_EXE'" - ); - my $sha1 = Exec::read_pipe_line(*OUT); - close(OUT); - - $sha1 = "Error getting SHA-1 Value" - if ((!defined $sha1) || ($sha1 eq "")); - - chop $sha1; - print "SHA-1 of istat output: $sha1\n"; - } - - print "\nImage: $Caseman::vol2path{$vol}\n"; - if (($Caseman::vol2start{$vol} == 0) && ($Caseman::vol2end{$vol} == 0)) { - print "Offset: Full image\n"; - } - elsif ($Caseman::vol2end{$vol} == 0) { - print "Offset: $Caseman::vol2start{$vol} to end\n"; - } - else { - print "Offset: $Caseman::vol2start{$vol} to $Caseman::vol2end{$vol}\n"; - } - print "File System Type: $ftype\n"; - - my $date = localtime(); - print "\nDate Generated: $date\n" - . "Investigator: $Args::args{'inv'}\n\n" - . "-" x 70 . "\n" - . " META DATA INFORMATION\n\n"; - - Exec::exec_pipe(*OUT, -"'$::TSKDIR/istat' -f $ftype $tz -s $Caseman::ts -o $offset -i $imgtype $img $meta" - ); - while ($_ = Exec::read_pipe_line(*OUT)) { - print $_; - } - close(OUT); - - if ($recmode == $File::REC_YES) { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -r -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - else { - Exec::exec_pipe(*OUT, -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $meta | '$::FILE_EXE' -z -b -" - ); - } - - my $file_type = Exec::read_pipe_line(*OUT); - close(OUT); - - $file_type = "Error getting file type" - if ((!defined $file_type) || ($file_type eq "")); - - print "\nFile Type: $file_type"; - - print "\n" - . "-" x 70 . "\n" - . " VERSION INFORMATION\n\n" - . "Autopsy Version: $::VER\n"; - print "The Sleuth Kit Version: " . ::get_tskver() . "\n"; - - Print::print_text_footer(); - - return 0; -} - -# Display the meta Allocation Table -sub list { - my $ILS_GAP = 500; - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $min = 0; - - $min = Args::get_min() if (exists $Args::args{'min'}); - my $max = $min + $ILS_GAP - 1; - - # Because we can not use metas 0 and 1 for most FS, set fmin to the - # minimum for this fs - my $fmin = $min; - $fmin = $Fs::first_meta{$ftype} if ($min < $Fs::first_meta{$ftype}); - - Print::print_html_header( - "$Fs::meta_str{$ftype} Allocation List $fmin -> $max"); - - Print::log_host_inv( -"$Caseman::vol2sname{$vol}: $Fs::meta_str{$ftype} Allocation List for $min to $max" - ); - - print "<center><H2>$Fs::meta_str{$ftype}: $fmin - $max</H2>"; - - # Display next and previous links - my $tmp; - if ($min > $Fs::first_meta{$ftype}) { - $tmp = $min - $ILS_GAP; - print -"<a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::LIST&$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " - . "width=\"89\" height=20 border=\"0\"></a> "; - } - $tmp = $min + $ILS_GAP; - print -" <a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::LIST&$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_next.jpg\" alt=\"next\" " - . "width=\"89\" height=20 border=\"0\"></a><br>"; - print "</center>\n"; - - # The list - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/ils' -e -s $Caseman::ts -f $ftype -o $offset -i $imgtype $img $fmin-$max" - ); - while ($_ = Exec::read_pipe_line(*OUT)) { - if (/^($::REG_META)\|([af])\|\d+\|\d+\|\d+\|\d+\|\d+\|/o) { - print -"<a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::STATS&$Args::baseargs&meta=$1\">" - . "$1:</a> "; - if ($2 eq "a") { - print "allocated<br>\n"; - } - else { - print "<font color=\"$::DEL_COLOR[0]\">free</font><br>\n"; - } - } - } - close(OUT); - - # Display next and previous links - print "<center>\n"; - if ($min > $Fs::first_meta{$ftype}) { - $tmp = $min - $ILS_GAP; - print -"<a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::LIST&$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_prev.jpg\" alt=\"previous\" " - . "width=\"89\" height=20 border=\"0\"></a> "; - } - $tmp = $min + $ILS_GAP; - print -" <a href=\"$::PROGNAME?mod=$::MOD_META&view=$Meta::LIST&$Args::baseargs&min=$tmp\">" - . "<img src=\"pict/but_next.jpg\" alt=\"next\" " - . "width=\"89\" height=20 border=\"0\"></a><br>"; - print "</center>\n"; - - Print::print_html_footer(); - return 0; - -} - -# Blank Page -sub blank { - Print::print_html_header("Metadata Blank Page"); - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - - print "<center><h3>Metadata Mode</h3><br>\n" - . "Here you can view the details about any $Fs::meta_str{$ftype} in the file system.<br>\n" - . "These are the data structures that store the file details.<br>\n" - . "Enter the address in the field on the left.\n"; - Print::print_html_footer(); - return 0; -} - diff --git a/lib/Notes.pm b/lib/Notes.pm deleted file mode 100644 index 5f36f1ad3e..0000000000 --- a/lib/Notes.pm +++ /dev/null @@ -1,1110 +0,0 @@ -# -# Notes and sequencer functions -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -package Notes; - -use POSIX; - -$Notes::ENTER_FILE = 1; -$Notes::ENTER_DATA = 2; -$Notes::WRITE_FILE = 3; -$Notes::WRITE_DATA = 4; -$Notes::WRITE_SEQ_MAN = 5; -$Notes::READ_NORM = 6; -$Notes::READ_SEQ = 7; - -sub main { - - # There is no default for Notes - Args::check_view(); - - Print::print_check_error("Notes option is not enabled") - if ($::USE_NOTES == 0); - - my $view = Args::get_view(); - - if ($view == $Notes::ENTER_FILE) { - return enter_file(); - } - elsif ($view == $Notes::ENTER_DATA) { - return enter_data(); - } - elsif ($view == $Notes::WRITE_FILE) { - return write_file(); - } - elsif ($view == $Notes::WRITE_DATA) { - return write_data(); - } - elsif ($view == $Notes::WRITE_SEQ_MAN) { - return write_seq_man(); - } - elsif ($view == $Notes::READ_NORM) { - return read_norm(); - } - elsif ($view == $Notes::READ_SEQ) { - return read_seq(); - } - else { - Print::print_check_err("Invalid Notes View"); - } -} - -sub investig_notes_fname { - return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.notes"; -} - -sub investig_seq_notes_fname { - return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.seq.notes"; -} - -# window where user can enter a normal and sequencer note for a file -# or meta data structure. -sub enter_file { - Args::check_vol('vol'); - Args::check_meta('meta'); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $mnt = $Caseman::vol2mnt{$vol}; - my $meta = Args::get_meta('meta'); - - # A file will have a 'dir' argument and a meta structure will not - if (exists $Args::args{'dir'}) { - my $fname = "$mnt$Args::args{'dir'}"; - Print::print_html_header("Notes for file $fname"); - print "<center><b>Enter a note for <tt>$fname</tt> ($meta):</b>" - . "<br><br>\n"; - } - else { - Print::print_html_header("Notes for $Fs::meta_str{$ftype} $meta"); - print "<center><b>Enter a note for $Fs::meta_str{$ftype} $meta:</b>" - . "<br><br>\n"; - } - print -"A note works like a bookmark and allows you to later find this data more easily.<br><br>\n"; - - # Setup the form - print "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<textarea rows=10 cols=50 wrap=\"virtual\" name=\"note\">" - . "</textarea><br>\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_NOTES\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Notes::WRITE_FILE\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . "<input type=\"hidden\" name=\"meta\" value=\"$meta\">\n" - . Args::make_hidden(); - - print "<input type=\"hidden\" name=\"dir\" value=\"$Args::args{'dir'}\">\n" - if (exists $Args::args{'dir'}); - - # Option to add a normal note - print "<input type=\"checkbox\" name=\"norm_note\" value=\"1\" CHECKED>\n" - . " Add a Standard Note<br>\n"; - - # Sequencer notes - which requires the MAC times for the files - if ("$Caseman::tz" ne "") { - $ENV{TZ} = $Caseman::tz; - POSIX: tzset(); - } - - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $meta_int = $meta; - $meta_int = $1 if ($meta_int =~ /^(\d+)-\d+(-\d+)?$/); - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/ils' -s $Caseman::ts -f $ftype -e -o $offset -i $imgtype $img $meta_int" - ); - - # Get the fourth line - my $tmp = Exec::read_pipe_line(*OUT); - $tmp = Exec::read_pipe_line(*OUT); - $tmp = Exec::read_pipe_line(*OUT); - $tmp = Exec::read_pipe_line(*OUT); - close(OUT); - unless ((defined $tmp) - && ($tmp =~ /^$::REG_META\|\w\|\d+\|\d+\|(\d+)\|(\d+)\|(\d+)\|/o)) - { - Print::print_err("Error parsing 'ils' output"); - } - - my $mtime = $1; - my $atime = $2; - my $ctime = $3; - - $mtime = localtime($mtime); - $atime = localtime($atime); - $ctime = localtime($ctime); - - # Print the Times - print "<br><hr><b>Add a Sequencer Event:</b><br><br>\n" - . "A sequencer event will be sorted based on the time so that event reconstruction will be easier<br><br>\n" - . "<input type=\"checkbox\" name=\"mtime\" value=\"1\">" - . "  M-Time (<tt>$mtime</tt>)<br>\n" - . "<input type=\"checkbox\" name=\"atime\" value=\"1\">" - . "  A-Time (<tt>$atime</tt>)<br>\n" - . "<input type=\"checkbox\" name=\"ctime\" value=\"1\">" - . "  C-Time (<tt>$ctime</tt>)<br><hr><br>\n"; - - # The OK Button - print "<br><input type=\"image\" src=\"pict/but_ok.jpg\" " - . "width=43 height=20 alt=\"Ok\" border=\"0\">\n</form>\n"; - - Print::print_html_footer(); - return 0; -} - -# data unit comment -sub enter_data { - Args::check_vol('vol'); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $block = Args::get_block(); - my $len = Args::get_len(); - - Print::print_html_header("Notes for $Fs::addr_unit{$ftype} $block"); - - print - "<center><b>Enter a note for $Fs::addr_unit{$ftype} $block</b><br><br>\n" - . "A note works like a bookmark and allows you to later find this data more easily.<br><br>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<textarea rows=10 cols=50 wrap=\"virtual\" name=\"note\">" - . "</textarea><br>\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_NOTES\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Notes::WRITE_DATA\">\n" - . "<input type=\"hidden\" name=\"vol\" value=\"$vol\">\n" - . "<input type=\"hidden\" name=\"block\" value=\"$block\">\n" - . "<input type=\"hidden\" name=\"len\" value=\"$len\">\n" - . "<input type=\"hidden\" name=\"norm_note\" value=\"1\">\n" - . Args::make_hidden() - . "<br><input type=\"image\" src=\"pict/but_ok.jpg\" " - . "width=43 height=20 alt=\"Ok\" border=\"0\">\n</form>\n"; - - Print::print_html_footer(); - return 0; - -} - -# Write the note to the note file -sub write_data { - Args::check_vol('vol'); - Args::check_block(); - Args::check_len(); - Args::check_note(); - - Print::print_html_header("Write a note"); - - my $vol = Args::get_vol('vol'); - my $ftype = $Caseman::vol2ftype{$vol}; - my $img_sh = $Caseman::vol2sname{$vol}; - my $block = Args::get_block(); - my $len = Args::get_len(); - - Print::log_host_inv( - "$img_sh: Creating note for $Fs::addr_unit{$ftype} $block"); - - my $notes_file = investig_notes_fname(); - open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; - print "Note added to $notes_file:<p>\n\n"; - - # Date - my $tmp = localtime(); - print NOTES "$tmp\n"; - print "$tmp<br>\n"; - - print NOTES "Volume: $vol $Fs::addr_unit{$ftype}: $block Len: $len\n"; - print "Volume: $vol $Fs::addr_unit{$ftype}: $block Len: $len<br>\n"; - - # The actual notes and a line at the bottom - print NOTES "\n$Args::args{'note'}\n\n" . "-" x 70 . "\n"; - print "<p>".Print::html_encode($Args::args{'note'})."<p>"; - close(NOTES); - - print "<hr>\n" - . "You can view the notes from the Host Manager View<p>" - . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_NORM\">" - . "<img border=0 src=\"pict/menu_b_note.jpg\" " - . "width=\"167\" height=20 alt=\"View Notes\"></a>\n"; - - Print::print_html_footer(); - - return 0; -} - -sub write_file { - Args::check_vol('vol'); - Args::check_meta('meta'); - Args::check_note(); - - # Get rid of carriage returns that Netscape adds - $Args::args{'note'} =~ tr/\r//d; - - my $vol = Args::get_vol('vol'); - my $mnt = $Caseman::vol2mnt{$vol}; - - my $ftype = $Caseman::vol2ftype{$vol}; - my $img_sh = $Caseman::vol2sname{$vol}; - my $meta = Args::get_meta('meta'); - - my $img = $Caseman::vol2path{$vol}; - my $offset = $Caseman::vol2start{$vol}; - my $imgtype = $Caseman::vol2itype{$vol}; - - my $fname = ""; - my $type = ""; - - if (exists $Args::args{'dir'}) { - $Args::args{'dir'} .= "/" - if ($Args::args{'dir'} eq ""); - $fname = "$mnt$Args::args{'dir'}"; - - if (($Args::args{'dir'} =~ /\/$/) || ($Args::args{'dir'} eq "")) { - Print::log_host_inv( - "$img_sh: Creating note for directory $fname ($meta)"); - $type = "dir"; - } - else { - Print::log_host_inv( - "$img_sh: Creating note for file $fname ($meta)"); - $type = "file"; - } - } - - else { - Print::log_host_inv( - "$img_sh: Creating note for $Fs::meta_str{$ftype} $meta"); - $type = "$Fs::meta_str{$ftype}"; - } - - Print::print_html_header("Writing a note / event"); - - # Get the times for the meta - # Set the timezone to the host zone - if ("$Caseman::tz" ne "") { - $ENV{TZ} = "$Caseman::tz"; - POSIX::tzset(); - } - - my $meta_int = $meta; - $meta_int = $1 if ($meta_int =~ /^(\d+)-\d+(-\d+)?$/); - local *OUT; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/ils' -s $Caseman::ts -f $ftype -e -o $offset -i $imgtype $img $meta_int" - ); - - # Skip to the fourth line - my $tmp = Exec::read_pipe_line(*OUT); - $tmp = Exec::read_pipe_line(*OUT); - $tmp = Exec::read_pipe_line(*OUT); - $tmp = Exec::read_pipe_line(*OUT); - unless ((defined $tmp) - && ($tmp =~ /^$::REG_META\|\w\|\d+\|\d+\|(\d+)\|(\d+)\|(\d+)\|/o)) - { - Print::print_err("Error parsing 'ils' output"); - } - my $mtime = $1; - my $atime = $2; - my $ctime = $3; - close(OUT); - - # Create a "normal" note - if ((exists $Args::args{'norm_note'}) && ($Args::args{'norm_note'} == 1)) { - - my $notes_file = investig_notes_fname(); - open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; - print "Note added to $notes_file:<p>\n\n"; - - # Date - my $tmp = localtime(); - print NOTES "$tmp\n"; - print "$tmp\n"; - - # We have a file name - if ($fname ne "") { - if ($type eq 'dir') { - print NOTES "Directory: $fname\n"; - print "Directory: $fname<br>\n"; - } - else { - print NOTES "File: $fname\n"; - print "File: $fname<br>\n"; - } - } - if ($meta ne "") { - print NOTES "Volume: $vol Meta: $meta\n"; - print "Volume: $vol Meta: $meta<br>\n"; - } - print NOTES "M-time: " . localtime($mtime) . "\n"; - print "M-time: " . localtime($mtime) . "<br>\n"; - print NOTES "A-time: " . localtime($atime) . "\n"; - print "A-time: " . localtime($atime) . "<br>\n"; - print NOTES "C-time: " . localtime($ctime) . "\n"; - print "C-time: " . localtime($ctime) . "<br>\n"; - - # The actual notes and a line at the bottom - print NOTES "\n$Args::args{'note'}\n\n" . "-" x 70 . "\n"; - print "<p>".Print::html_encode($Args::args{'note'})."<p>"; - - close(NOTES); - } - - # Create a sequencer event - if there are any - unless (((exists $Args::args{'mtime'}) && ($Args::args{'mtime'} == 1)) - || ((exists $Args::args{'atime'}) && ($Args::args{'atime'} == 1)) - || ((exists $Args::args{'ctime'}) && ($Args::args{'ctime'} == 1))) - { - - print "<hr>\n" - . "You can view the notes from the Host Manager View<p>" - . "<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_NORM\">" - . "<img border=0 src=\"pict/menu_b_note.jpg\" " - . "width=\"167\" height=20 alt=\"View Notes\"></a>\n"; - - Print::print_html_footer(); - - return 0; - } - - # Get rid of the carriage returns - $Args::args{'note'} =~ s/\n/<br>/gs; - - my $notes_file = investig_seq_notes_fname(); - open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; - - if ((exists $Args::args{'mtime'}) && ($Args::args{'mtime'} == 1)) { - - my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = - localtime($mtime); - $year += 1900; - $mon += 1; - $mday = "0$mday" if ($mday < 10); - $hour = "0$hour" if ($hour < 10); - $min = "0$min" if ($min < 10); - $sec = "0$sec" if ($sec < 10); - - print NOTES "'$year','$mon','$mday','$hour','$min','$sec'," - . "'$Args::args{'host'}','$vol','$fname','$meta',''," - . "'$type','[M-Time]$Args::args{'note'}'\n"; - - Print::log_host_inv( - "$img_sh: M-Time note added for meta $Args::args{'meta'}"); - print "M-Time sequence event added<br>\n"; - } - - if ((exists $Args::args{'atime'}) && ($Args::args{'atime'} == 1)) { - my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = - localtime($atime); - $year += 1900; - $mon += 1; - $mday = "0$mday" if ($mday < 10); - $hour = "0$hour" if ($hour < 10); - $min = "0$min" if ($min < 10); - $sec = "0$sec" if ($sec < 10); - - print NOTES "'$year','$mon','$mday','$hour','$min','$sec'," - . "'$Args::args{'host'}','$vol','$fname','$meta',''," - . "'$type','[A-Time]$Args::args{'note'}'\n"; - - Print::log_host_inv( - "$img_sh: A-Time note added for meta $Args::args{'meta'}"); - print "A-Time sequence event added<br>\n"; - } - - if ((exists $Args::args{'ctime'}) && ($Args::args{'ctime'} == 1)) { - my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = - localtime($ctime); - $year += 1900; - $mon += 1; - $mday = "0$mday" if ($mday < 10); - $hour = "0$hour" if ($hour < 10); - $min = "0$min" if ($min < 10); - $sec = "0$sec" if ($sec < 10); - - print NOTES "'$year','$mon','$mday','$hour','$min','$sec'," - . "'$Args::args{'host'}','$vol','$fname','$meta',''," - . "'$type','[C-Time]$Args::args{'note'}'\n"; - - Print::log_host_inv( - "$img_sh: C-Time note added for meta $Args::args{'meta'}"); - print "C-Time sequence event added<br>\n"; - } - - close(NOTES); - - print "<p><hr>\n" - . "You can view the notes and events from the Host Manager View<p>"; - - if ((exists $Args::args{'norm_note'}) && ($Args::args{'norm_note'} == 1)) { - print -"<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_NORM\">" - . "<img border=0 src=\"pict/menu_b_note.jpg\" " - . "width=\"167\" height=20 alt=\"View Notes\"></a>\n"; - } - - print -"<a href=\"$::PROGNAME?${Args::baseargs_novol}&mod=$::MOD_NOTES&view=$Notes::READ_SEQ\">" - . "<img border=0 src=\"pict/menu_b_seq.jpg\" width=\"167\" height=\"20\" " - . " alt=\"Event Sequencer\"></a>\n"; - - Print::print_html_footer(); - - return 0; -} - -# Display the contents of the "normal" notes file -sub read_norm { - Print::print_html_header("Contents of Notes File"); - - my $notes_file = investig_notes_fname(); - - Print::log_host_inv("Viewing contents of notes file ($notes_file)"); - if ((!(-e "$notes_file")) || (-z "$notes_file")) { - print "No notes have been entered yet.<br>\n" - . "They can be entered using the <i>Add Note</i> link within each analysis mode.<br>\n"; - return; - } - - open NOTES, "<$notes_file" or die "Can't open log: $notes_file"; - - my $file = ""; - my $dir = ""; - - print "<table width=100%>\n" - . "<tr bgcolor=$::BACK_COLOR><td align=left>\n"; - - my $row = 0; - - # This will need to change whenever the log format changes - while (<NOTES>) { - - # we need to extract mnt from here - $file = $1 if (/^File: (.*)$/); - $dir = $1 if (/^Directory: (.*)$/); - - # Reset the $file if we are at the end of the current note - if (/^\-+$/) { - $file = ""; - $dir = ""; - if (($row++ % 2) == 0) { - print -"</td></tr>\n<tr bgcolor=$::BACK_COLOR_TABLE><td align=left>\n"; - } - else { - print "</td></tr>\n<tr bgcolor=$::BACK_COLOR><td align=left>\n"; - } - } - else { - print Print::html_encode($_); - } - - if (/^Volume: ($::REG_VNAME) Meta: ([0-9\-]+)/o) { - $vol = $1; - $meta = $2; - next unless (exists $Caseman::vol2cat{$vol}); - - # file note - if ($file ne "") { - - # extract the prepended mnt value - my $mnt = $Caseman::vol2mnt{$vol}; - my $fname = ""; - $fname = $1 if ($file =~ /^$mnt\/?(.*)$/); - print "<a href=\"$::PROGNAME?$Args::baseargs_novol" - . "&mod=$::MOD_FILE&view=$File::CONT_FR" - . "&vol=$vol&meta=$meta&dir=$fname\" target=\"_blank\">" - . "<img src=\"pict/but_view.jpg\" alt=\"view\" " - . "width=45 height=22 alt=\"View\" border=\"0\"></a><br>\n"; - } - - # directory note - elsif ($dir ne "") { - - # extract the prepended mnt value - my $mnt = $Caseman::vol2mnt{$vol}; - my $fname = ""; - $fname = $1 if ($dir =~ /^$mnt\/?(.*)$/); - print "<a href=\"$::PROGNAME?$Args::baseargs_novol" - . "&mod=$::MOD_FRAME&submod=$::MOD_FILE&vol=$vol&" - . "&meta=$meta&dir=$fname\" target=\"_blank\">" - . "<img src=\"pict/but_view.jpg\" alt=\"view\" " - . "width=45 height=22 alt=\"View\" border=\"0\"></a><br>\n"; - - } - - # meta note - else { - print "<a href=\"$::PROGNAME?$Args::baseargs_novol" - . "&mod=$::MOD_FRAME&submod=$::MOD_META&vol=$vol" - . "&meta=$meta\" target=\"_blank\">" - . "<img src=\"pict/but_view.jpg\" alt=\"view\" " - . "width=45 height=22 alt=\"View\" border=\"0\"></a><br>\n"; - - } - } - - # block note - elsif (/^Volume: ($::REG_VNAME) \w+: ([0-9]+) Len: (\d+)/o) { - $vol = $1; - $blk = $2; - $len = $3; - next unless (exists $Caseman::vol2cat{$vol}); - - print "<a href=\"$::PROGNAME?$Args::baseargs_novol" - . "&mod=$::MOD_FRAME&submod=$::MOD_DATA&vol=$vol" - . "&block=$blk&len=$len\" target=\"_blank\">" - . "<img src=\"pict/but_view.jpg\" alt=\"view\" " - . "width=45 height=22 alt=\"View\" border=\"0\"></a><br>\n"; - - } - } - - print "</tr></table>\n"; - - # Ok and refresh buttons - print "<p><center><table width=600>\n" - . "<tr><td width=300 align=center>\n" - . "<a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&view=$Caseman::VOL_OPEN&$Args::baseargs\">" - . "<img border=0 src=\"pict/menu_b_close.jpg\" width=167 height=20 alt=\"close\"></a>\n" - . "</td><td width=300 align=center>\n" - . "<a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::READ_NORM&$Args::baseargs\">" - . "<img border=0 src=\"pict/menu_b_ref.jpg\" width=167 height=20 alt=\"refresh\"></a>\n" - . "</td></tr></table>\n"; - - close(NOTES); - - Print::print_html_footer(); - - return 0; -} - -######################################################################### -# Sequencer Code - -# Write a sequence event that was manually entered -sub write_seq_man { - - Args::check_note(); - - Print::print_html_header("Writing Sequencer Event"); - - # Get rid of carriage returns that Netscape adds - $Args::args{'note'} =~ tr/\r//d; - $Args::args{'note'} =~ s/\n/<br>/gs; - - if ($Args::args{'note'} eq "") { - print( "A comment must be given for the event<br>\n" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::READ_SEQ&$Args::baseargs\">" - . "<img border=0 src=\"pict/menu_b_ok.jpg\" " - . "width=167 height=20></a>"); - Print::print_err("\n"); - } - - # Check the args and add them to the final string that will be written - my $str = ""; - unless ((exists $Args::args{'year'}) - && ($Args::args{'year'} =~ /^(\d\d\d\d)$/)) - { - Print::print_err("Invalid year"); - } - $str .= "'$1',"; - - unless ((exists $Args::args{'mon'}) && ($Args::args{'mon'} =~ /^(\d\d?)$/)) - { - Print::print_err("Invalid month"); - } - $str .= "'$1',"; - - unless ((exists $Args::args{'day'}) && ($Args::args{'day'} =~ /^(\d\d?)$/)) - { - Print::print_err("Invalid day"); - } - $str .= "'$1',"; - - unless ((exists $Args::args{'hour'}) - && ($Args::args{'hour'} =~ /^(\d\d?)$/)) - { - Print::print_err("Invalid hour"); - } - $str .= "'$1',"; - - unless ((exists $Args::args{'min'}) && ($Args::args{'min'} =~ /^(\d\d?)$/)) - { - Print::print_err("Invalid min"); - } - $str .= "'$1',"; - - unless ((exists $Args::args{'sec'}) && ($Args::args{'sec'} =~ /^(\d\d?)$/)) - { - Print::print_err("Invalid sec"); - } - $str .= "'$1',"; - - # There are no image, meta, file name, or data unit for this type - $str .= "'$Args::args{'host'}','','','','',"; - - unless ((exists $Args::args{'src'}) && ($Args::args{'src'} =~ /^(\w+)$/)) { - Print::print_err("Invalid src"); - } - $str .= "'$1','$Args::args{'note'}'\n"; - - # Write the string to the notes file - my $notes_file = investig_seq_notes_fname(); - open NOTES, ">>$notes_file" or die "Can't open log: $notes_file"; - print NOTES $str; - close(NOTES); - - # Send a message to the user - print "Event Added to Sequencer file:<br><br>\n" - . "$::d2m[$Args::args{'mon'}] $Args::args{'day'}, $Args::args{'year'} " - . "$Args::args{'hour'}:$Args::args{'min'}:$Args::args{'sec'}<br><br>\n" - . Print::html_encode($Args::args{'note'})."<br>\n" - . "<p><a href=\"$::PROGNAME?mod=$::MOD_NOTES&view=$Notes::READ_SEQ&$Args::baseargs&" - . "year=$Args::enc_args{'year'}&mon=$Args::enc_args{'mon'}&day=$Args::enc_args{'day'}&" - . "hour=$Args::enc_args{'hour'}&min=$Args::enc_args{'min'}&sec=$Args::enc_args{'sec'}\">" - . "<img border=0 src=\"pict/but_ok.jpg\" alt=\"Ok\" " - . "width=43 height=20></a>\n"; - - Print::print_html_footer(); - return 0; -} - -# View the sequencer file -sub read_seq { - - Print::print_html_header("Event Sequencer"); - - print "<center>\n" . "<h3>Event Sequencer</h3>\n"; - - my $cnt = 0; - my @entry; - my ( - @year, @mon, @day, @hour, @min, @sec, @host, - @vol, @fname, @meta, @data, @type, @note - ); - - # Read the sequencer file into arrays that will be sorted - my $notes_file = investig_seq_notes_fname(); - if (-e $notes_file) { - - open NOTES, "$notes_file" or die "Can't open log: $notes_file"; - while (<NOTES>) { - - unless ( -/^'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?(\d+)'?,'?($::REG_HOST)'?,'?($::REG_VNAME)?'?,'?(.*?)'?,'?($::REG_META)?'?,'?(\d+)?'?,'?([\w\s]+)'?,'?(.*?)'?$/ - ) - { - Print::print_err("Error parsing sequence event entry: $_"); - } - - $year[$cnt] = $1; - $mon[$cnt] = $2; - $day[$cnt] = $3; - $hour[$cnt] = $4; - $min[$cnt] = $5; - $sec[$cnt] = $6; - $host[$cnt] = $7; - $vol[$cnt] = $8; - $fname[$cnt] = ""; - $fname[$cnt] = $9 if (defined $9); - $meta[$cnt] = ""; - $meta[$cnt] = $10 if (defined $10); - $data[$cnt] = ""; - $data[$cnt] = $11 if (defined $11); - $type[$cnt] = $12; - $note[$cnt] = $13; - - $entry[$cnt] = $cnt; - $cnt++; - } - - close(NOTES); - - # Sort the values by date, source, and then note - my @sorted = sort { - $year[$a] <=> $year[$b] - or $mon[$a] <=> $mon[$b] - or $day[$a] <=> $day[$b] - or $hour[$a] <=> $hour[$b] - or $min[$a] <=> $min[$b] - or $sec[$a] <=> $sec[$b] - or lc($type[$a]) cmp lc($type[$b]) - or lc($note[$a]) cmp lc($note[$b]) - } @entry; - - # Table and header - print "<table width=800 border=1>\n" - . "<tr background=\"$::YEL_PIX\">\n" - . "<th>Date & Time</th>\n" - . "<th>Source</th>\n" - . "<th>Event & Note</th></tr>\n"; - - # Cycle through the sorted events - my $row = 0; - foreach my $i (@sorted) { - - # Alternate row colors - if (($row % 2) == 0) { - print "<tr bgcolor=\"$::BACK_COLOR\">\n"; - } - else { - print "<tr bgcolor=\"$::BACK_COLOR_TABLE\">\n"; - } - - # Date & Time - print "<td align=left valign=top>\n" - . "$::d2m[$mon[$i]] $day[$i], $year[$i]" - . " $hour[$i]:$min[$i]:$sec[$i]</td>" - . "<td align=left valign=top>\n"; - - # If there is as name, then we will show it - # @@@ Why does an error message come up from here: - # Use of uninitialized value in string ne at - if ($fname[$i] ne "") { - - if ( (exists $vol[$i]) - && (defined $vol[$i]) - && ($vol[$i] ne "") - && (exists $Caseman::vol2mnt{$vol[$i]}) - && (exists $meta[$i])) - { - - # extract the prepended mnt value - my $mnt = $Caseman::vol2mnt{$vol[$i]}; - my $fname = ""; - $fname = $1 if ($fname[$i] =~ /^$mnt\/?(.*)$/); - - # Check if it is a directory - if ($type[$i] eq 'dir') { - print "<a href=\"$::PROGNAME?mod=$::MOD_FRAME&" - . "submod=$::MOD_FILE&vol=$vol[$i]&$Args::baseargs&meta=$meta[$i]&dir=$fname\" " - . "target=\"_blank\">\n" - . "<tt>$fname[$i]</tt></a>\n"; - } - else { - print "<a href=\"$::PROGNAME?mod=$::MOD_FILE&" - . "view=$File::CONT_FR&vol=$vol[$i]&$Args::baseargs&meta=$meta[$i]&dir=$fname\" " - . "target=\"_blank\">\n" - . "<tt>$fname[$i]</tt></a>\n"; - } - } - else { - print "<tt>$fname[$i]</tt>\n"; - } - } - - # Display the meta value if there was no name - elsif (($vol[$i] ne "") && (defined $meta[$i]) && ($meta[$i] ne "")) - { - my $ftype = $Caseman::vol2ftype{$vol[$i]}; - - # Include a link if we can - if (exists $Caseman::vol2mnt{$vol[$i]}) { - print "<a href=\"$::PROGNAME?mod=$::MOD_FRAME&" - . "submod=$::MOD_META&vol=$vol[$i]" - . "&$Args::baseargs&meta=$meta[$i]\" target=\"_blank\">\n" - . "$Fs::meta_str{$ftype}: $meta[$i]</a>\n"; - } - else { - print "$Fs::meta_str{$ftype}: $meta[$i]\n"; - } - } - - # Otherwise, just give the source type - else { - print "$type[$i]\n"; - } - print "</td>\n"; - - # Print the actual note - $note[$i] = Print::html_encode($note[$i]); - $note[$i] = " " if ($note[$i] eq ""); - print "<td align=left>$note[$i]</td></tr>\n"; - - $row++; - } - - print "</table>\n"; - - } - - # End of if file exists - else { - print "No events currently exist<br>\n"; - } - - # Ok and refresh buttons - print "<p><table width=600>\n" - . "<tr><td width=300 align=center>\n" - . "<a href=\"$::PROGNAME?mod=$::MOD_CASEMAN&" - . "view=$Caseman::VOL_OPEN&$Args::baseargs\">" - . "<img border=0 src=\"pict/menu_b_close.jpg\" width=167 height=20 alt=\"close\"></a>\n" - . "</td><td width=300 align=center>\n" - . "<a href=\"$::PROGNAME?mod=$::MOD_NOTES&" - . "view=$Notes::READ_SEQ&$Args::baseargs\">" - . "<img border=0 src=\"pict/menu_b_ref.jpg\" width=167 height=20 alt=\"refresh\"></a>\n" - . "</td></tr></table>\n"; - - # Manually add a new event - print "<hr>\n" - . "<b>Add a New Event</b><br><br>\n" - . "<form action=\"$::PROGNAME\" method=\"get\">\n" - . "<textarea rows=10 cols=50 wrap=\"virtual\" name=\"note\">" - . "</textarea><br>\n" - . "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_NOTES\">\n" - . "<input type=\"hidden\" name=\"view\" value=\"$Notes::WRITE_SEQ_MAN\">\n" - . Args::make_hidden(); - - # Month - print "<table><tr><td align=\"left\">\n"; - print "<p>Date: " . "<select name=\"mon\" size=\"1\">\n"; - - my $prev = 1; - $prev = $Args::args{'mon'} - if ((exists $Args::args{'mon'}) && ($Args::args{'mon'} =~ /^\d+$/)); - - for my $i (1 .. 12) { - if ($i == $prev) { - print "<option value=$i selected>$::d2m[$i]</option>\n"; - } - else { - print "<option value=\"$i\">$::d2m[$i]</option>\n"; - } - } - - print "</select>\n"; - - # Day - print " <select name=\"day\" size=\"1\">\n"; - - $prev = 1; - $prev = $Args::args{'day'} - if ((exists $Args::args{'day'}) && ($Args::args{'day'} =~ /^\d+$/)); - - for my $i (1 .. 31) { - my $dstr = $i; - $dstr = "0$i" if ($i < 10); - - if ($prev eq $dstr) { - print "<option value=\"$dstr\" selected>$dstr</option>\n"; - } - else { - print "<option value=\"$dstr\">$dstr</option>\n"; - } - } - print "</select>\n"; - - # Year - $prev = 1900 + (localtime())[5]; - $prev = $Args::args{'year'} - if ((exists $Args::args{'year'}) && ($Args::args{'year'} =~ /^\d+$/)); - - print " <input type=\"text\" value=\"$prev\" " - . "name=\"year\" size=\"6\">\n"; - - # Hour - print "  <select name=\"hour\" size=\"1\">\n"; - $prev = 0; - $prev = $Args::args{'hour'} - if ((exists $Args::args{'hour'}) && ($Args::args{'hour'} =~ /^\d+$/)); - - for my $i (0 .. 23) { - my $hstr = $i; - $hstr = "0$i" if ($i < 10); - - if ($prev eq $hstr) { - print "<option value=\"$hstr\" selected>$hstr</option>\n"; - } - else { - print "<option value=\"$hstr\">$hstr</option>\n"; - } - } - print "</select>\n"; - - # Min - print ":<select name=\"min\" size=\"1\">\n"; - $prev = 0; - $prev = $Args::args{'min'} - if ((exists $Args::args{'min'}) && ($Args::args{'min'} =~ /^\d+$/)); - - for my $i (0 .. 59) { - my $mstr = $i; - $mstr = "0$i" if ($i < 10); - if ($prev eq $mstr) { - print "<option value=\"$mstr\" selected>$mstr</option>\n"; - } - else { - print "<option value=\"$mstr\">$mstr</option>\n"; - } - } - print "</select>\n"; - - # Sec - print ":<select name=\"sec\" size=\"1\">\n"; - $prev = 0; - $prev = $Args::args{'sec'} - if ((exists $Args::args{'sec'}) && ($Args::args{'sec'} =~ /^\d+$/)); - - for my $i (0 .. 59) { - my $sstr = $i; - $sstr = "0$i" if ($i < 10); - - if ($prev eq $sstr) { - print "<option value=\"$sstr\" selected>$sstr</option>\n"; - } - else { - print "<option value=\"$sstr\">$sstr</option>\n"; - } - } - print "</select></td></tr>\n" . "<tr><td> </td></tr>\n"; - - # Type - print "<tr><td align=\"left\">Event Source: <select name=\"src\" size=1>\n" - . "<option value=\"firewall\">firewall</option>\n" - . "<option value=\"ids\">ids</option>\n" - . "<option value=\"isp\">isp</option>\n" - . "<option value=\"log\">log</option>\n" - . "<option value=\"other\" selected>other</option>\n" - . "<option value=\"person\">person</option>\n" - . "</select></td></tr>\n" - . "<tr><td> </td></tr>\n"; - - print -"<tr><td align=\"center\"><input type=\"image\" src=\"pict/menu_b_add.jpg\" " - . "width=167 height=20 alt=\"Add\" border=\"0\">\n</form></td></tr></table>\n"; - - Print::print_html_footer(); - return 0; -} - -# Conver the 'image' format to the 'volume' format -sub convert { - my %img2vol = %{shift()}; - - my @invs = Caseman::read_invest(); - if (scalar @invs == 0) { - push @invs, "unknown"; - } - - foreach $i (@invs) { - my $notes_file = "$::host_dir" . "$::LOGDIR/$i.notes"; - - if ((!(-e "$notes_file")) || (-z "$notes_file")) { - next; - } - Print::log_host_info( - "Converting format of notes file for $i ($notes_file)"); - - open NOTES, "<$notes_file" or die "Can't open log: $notes_file"; - - my $notes_file_new = $notes_file . ".new"; - open NOTES_NEW, ">$notes_file_new" - or die "Can't open writing log: $notes_file_new"; - - while (<NOTES>) { - - if (/Image: ($::REG_IMG)\s+(.*)$/) { - my $img = $1; - my $addr = $2; - - unless (exists $img2vol{$img}) { - print STDERR -"Error finding image during notes conversion: $img. Not converting\n"; - next; - } - my $vol = $img2vol{$img}; - - # Convert old description to last versions - $addr =~ s/Inode:/Meta:/; - print NOTES_NEW "Volume: $vol $addr\n"; - } - else { - print NOTES_NEW $_; - } - } - - close(NOTES); - close(NOTES_NEW); - rename $notes_file, $notes_file . ".bak"; - rename $notes_file_new, $notes_file; - } - - # NOw do sequence notes - foreach $i (@invs) { - my $notes_file = "$::host_dir" . "$::LOGDIR/$i.seq.notes"; - if ((!(-e "$notes_file")) || (-z "$notes_file")) { - next; - } - - open NOTES, "$notes_file" or die "Can't open log: $notes_file"; - - $notes_file_new = $notes_file . ".new"; - open NOTES_NEW, ">$notes_file_new" - or die "Can't open log for updating: $notes_file_new"; - - while (<NOTES>) { - - # No image in entry - if (/^'\d+','\d+','\d+','\d+','\d+','\d+','$::REG_HOST','','/) { - print NOTES_NEW $_; - } - elsif ( -/^('\d+','\d+','\d+','\d+','\d+','\d+','$::REG_HOST',')($::REG_IMG)(','.*)$/ - ) - { - my $pre = $1; - my $img = $2; - my $post = $3; - unless (exists $img2vol{$img}) { - print STDERR -"Error finding image during notes conversion: $img. Not converting\n"; - next; - } - my $vol = $img2vol{$img}; - print NOTES_NEW $pre . $vol . $post . "\n"; - } - else { - print NOTES_NEW "$_"; - return; - } - } - - close(NOTES); - close(NOTES_NEW); - rename $notes_file, $notes_file . ".bak"; - rename $notes_file_new, $notes_file; - } - - return 0; -} diff --git a/lib/Print.pm b/lib/Print.pm deleted file mode 100644 index 417caa70f4..0000000000 --- a/lib/Print.pm +++ /dev/null @@ -1,390 +0,0 @@ -package Print; - -# -# Utilities to print information -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -# Escape HTML entities -# Converts \n to <br>\n -sub html_encode { - my $text = shift; - $text =~ s/&/&/gs; - $text =~ s/</</gs; - $text =~ s/>/>/gs; - $text =~ s/\"/"/gs; - $text =~ s/\n/<br>\n/gs; - - # @@@ LEADING SPACES and TABS - # while ($text =~ s/^( )*\t/"$1    "/eig) {} - # while ($text =~ s/^( )* /"$1 "/eig) {} - return $text; -} - -# remove control chars from printout -# this does not escape HTML entities, so you can pass this HTML code -sub print_output { - my $out = shift; - print "$out"; - - while (my $out = shift) { - foreach $_ (split(//, $out)) { - if ( ($_ eq "\n") - || ($_ eq "\r") - || ($_ eq "\f") - || ($_ eq "\t")) - { - print "$_"; - } - elsif ((ord($_) < 0x20) && (ord($_) >= 0x00)) { - print "^" . ord($_); - } - else { - print "$_"; - } - } - } -} - -# Added to provide output in hexdump format -# function gets called on a per-icat basis, -# The offset value is the byte offset that this data -# starts at, since the File.pm code calls it in 1024 -# byte chunks) -sub print_hexdump { - my $out = shift; # data to output - my $offset = shift; # starting byte offset in file - my $buf = ""; - - foreach $i (split(//, $out)) { - my $idx = $offset % 16; - - if ($idx == 0) { - printf("%08X: ", $offset); - } - - printf("%02X", ord($i)); - if (($idx % 2) == 1) { - printf(" "); - } - - $buf[$idx] = $i; - - if ($idx == 15) { - print " "; - for (my $j = 0; $j < 16; $j++) { - if ($buf[$j] =~ m/[ -~]/) { - print $buf[$j]; - } - else { - print "."; - } - $buf[$j] = 0; - } - print "\n"; - } - $offset++; - } - - # print out last line if < 16 bytes long - my $l = $offset % 16; - - if ($l) { - my $t = (16 - $l) * 2 + (16 - $l) / 2; - for (my $j = 0; $j < $t; $j++) { - print " "; - } - print " "; - for (my $j = 0; $j < $l; $j++) { - if ($buf[$j] =~ m/[ -~]/) { - print $buf[$j]; - } - else { - print "."; - } - } - print "\n"; - } -} - -############################################ -# -# HTTP/HTML Headers and Footers - -# The page that makes the frameset does not have a body statement -# This routine is used to make the minimum required header statements -sub print_html_header_frameset { - my $text = shift; - print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; - - my $time = localtime(); - - print <<EOF; -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<!-- Autopsy ver. $::VER Forensic Browser --> -<!-- Page created at: $time --> -<head> - <title>$text - - - - -EOF -} - -sub print_html_footer_frameset { - print "\n\n" . "$::HTTP_NL$::HTTP_NL"; -} - -# Create the header information with the body tag -sub print_html_header { - print_html_header_frameset(shift); - print "\n\n"; - print "\n"; -} - -sub print_html_footer { - print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; -} - -# Print the header with the margins set to 0 so that the tab buttons -# are flush with the edges of the frame -sub print_html_header_tabs { - print_html_header_frameset(shift); - print "\n\n"; - print "\n"; - $is_body = 1; -} - -sub print_html_footer_tabs { - print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; -} - -# Header for front page to warn about java script -sub print_html_header_javascript { - my $text = shift; - print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; - - my $time = localtime(); - - # The write line has to stay on one line - print < - - - - - $text - - - - - - - - -EOF -} - -sub print_html_footer_javascript { - print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; -} - -# For raw text outputs (Pass the name of a file if it is being saved) -sub print_text_header { - print "Content-Type: text/plain; charset=utf-8$::HTTP_NL"; - if (scalar @_ > 0) { - my $fname = shift(); - print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; - } - print "$::HTTP_NL"; -} - -sub print_text_footer { - print "$::HTTP_NL$::HTTP_NL"; -} - -# For forced save outputs -sub print_oct_header { - print "Content-Type: application/octet-stream$::HTTP_NL"; - if (scalar @_ > 0) { - my $fname = shift(); - print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; - } - print "$::HTTP_NL"; -} - -sub print_oct_footer { -} - -# Error message that is used when an HTTP/HTML header is needed -# This escapes the characters that chould be HTML entities. -# it will also replace \n with
and other things that html_encode() -# can do. Do not send arbitrary HTML to this function. -sub print_check_err { - print_html_header(""); - print html_encode(shift()) . "
\n"; - print_html_footer(); - sleep(1); - exit 1; -} - -# Error message when header already exists -# This escapes the characters that chould be HTML entities. -# it will also replace \n with
and other things that html_encode() -# can do. Do not send arbitrary HTML to this function. -sub print_err { - print html_encode(shift()) . "
\n"; - sleep(1); - print_html_footer(); - exit 1; -} - -################################################################## -# -# Logging -# -# - -sub investig_log_fname { - return "" unless (defined $::host_dir && $::host_dir ne ""); - return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); - - return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.log"; -} - -sub investig_exec_log_fname { - return "" unless (defined $::host_dir && $::host_dir ne ""); - return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); - - return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.exec.log"; -} - -sub host_log_fname { - return "" unless (defined $::host_dir && $::host_dir ne ""); - - return "$::host_dir" . "$::LOGDIR/host.log"; -} - -sub case_log_fname { - return "" unless (defined $::case_dir && $::case_dir ne ""); - - return "$::case_dir" . "case.log"; -} - -# Log data to the investigators specific log file -sub log_host_inv { - return unless ($::USE_LOG == 1); - - my $str = shift; - chomp $str; - - my $date = localtime; - my $fname = investig_log_fname(); - return if ($fname eq ""); - - open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; - print HOSTLOG "$date: $str\n"; - close(HOSTLOG); - - return; -} - -sub log_host_inv_exec { - return unless ($::USE_LOG == 1); - my $str = shift; - chomp $str; - - my $date = localtime; - my $fname = investig_exec_log_fname(); - return if ($fname eq ""); - - open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; - print HOSTLOG "$date: $str\n"; - close(HOSTLOG); - - return; -} - -# log data to the general log file for the host -sub log_host_info { - return unless ($::USE_LOG == 1); - - my $str = shift; - chomp $str; - - my $date = localtime; - my $fname = host_log_fname(); - return if ($fname eq ""); - - open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; - print HOSTLOG "$date: $str\n"; - close(HOSTLOG); - - return; -} - -sub log_case_info { - return unless ($::USE_LOG == 1); - my $str = shift; - chomp $str; - my $date = localtime; - my $fname = case_log_fname(); - return if ($fname eq ""); - - open CASELOG, ">>$fname" or die "Can't open log: $fname"; - print CASELOG "$date: $str\n"; - close(CASELOG); - - return; -} - -sub log_session_info { - return unless ($::USE_LOG == 1); - my $str = shift; - chomp $str; - my $date = localtime; - - my $lname = "autopsy.log"; - open AUTLOG, ">>$::LOCKDIR/$lname" or die "Can't open log: $lname"; - print AUTLOG "$date: $str\n"; - close(AUTLOG); - - return; -} - -1; diff --git a/lib/Timeline.pm b/lib/Timeline.pm deleted file mode 100644 index 4cd676af93..0000000000 --- a/lib/Timeline.pm +++ /dev/null @@ -1,1425 +0,0 @@ -# -# Timeline functions -# -# Brian Carrier [carrier@sleuthkit.org] -# Copyright (c) 2001-2005 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 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. - -package Timeline; - -use POSIX; # needed for tzset - -# Changing the order of this may affect the main function ordering - -$Timeline::BLANK = 0; -$Timeline::FRAME = 1; -$Timeline::TABS = 2; -$Timeline::BODY_ENTER = 3; -$Timeline::BODY_RUN = 4; -$Timeline::TL_ENTER = 5; -$Timeline::TL_RUN = 6; -$Timeline::VIEW_FR = 7; -$Timeline::VIEW_MENU = 8; -$Timeline::VIEW_IDX = 9; -$Timeline::VIEW_SUM = 10; -$Timeline::VIEW = 11; - -# Types of modes for fname (i.e. can we overwrite it if it exists) -my $FNAME_MODE_INIT = 0; -my $FNAME_MODE_OVER = 1; - -sub main { - - return if ($::LIVE == 1); - - # By default, show the main frame - $Args::args{'view'} = $Args::enc_args{'view'} = $Timeline::FRAME - unless (exists $Args::args{'view'}); - - Args::check_view(); - my $view = Args::get_view(); - - if ($view < $Timeline::VIEW_FR) { - if ($view == $Timeline::BLANK) { - return blank(); - } - elsif ($view == $Timeline::FRAME) { - return frame(); - } - elsif ($view == $Timeline::TABS) { - return tabs(); - } - elsif ($view == $Timeline::BODY_ENTER) { - return body_enter(); - } - elsif ($view == $Timeline::BODY_RUN) { - return body_run(); - } - elsif ($view == $Timeline::TL_ENTER) { - return tl_enter(); - } - elsif ($view == $Timeline::TL_RUN) { - return tl_run(); - } - } - else { - if ($view == $Timeline::VIEW_FR) { - return view_fr(); - } - elsif ($view == $Timeline::VIEW_MENU) { - return view_menu(); - } - elsif ($view == $Timeline::VIEW_IDX) { - return view_idx(); - } - elsif ($view == $Timeline::VIEW_SUM) { - return view_sum(); - } - elsif ($view == $Timeline::VIEW) { - return view(); - } - } - Print::print_check_err("Invalid Timeline View"); -} - -# Call the appropriate function based on the value of sort -sub frame { - Print::print_html_header_frameset( - "Timeline: $Args::args{'case'}:$Args::args{'host'}"); - - print "\n"; - - my $submod = $Timeline::BLANK; - $submod = Args::get_submod() if (exists $Args::args{'submod'}); - - # Listing - print "\n"; - - my $str = ""; - - # Contents - if ($submod == $Timeline::BLANK) { - print -"\n\n"; - return; - } - elsif ($submod == $Timeline::TL_ENTER) { - $str .= "&body=$Args::args{'body'}" if (exists $Args::args{'body'}); - } - elsif ($submod == $Timeline::VIEW_FR) { - $str .= "&tl=$Args::args{'tl'}" if (exists $Args::args{'tl'}); - } - - print -"\n\n"; - - Print::print_html_footer_frameset(); - return 0; -} - -# The tabs / button images in timeline view -sub tabs { - Args::check_submod(); - Print::print_html_header_tabs("Timeline Mode Tabs"); - - my $submod = Args::get_submod(); - - print "
\n"; - - # Create Datafile - print "\n" - . "\n" - . "\n" . "\n"; - } - else { - print "\n"; - } - - # Help - set to current submod - print "\n"; - - # Close - print "\n" - . "
" - . ""; - - if ($submod == $Timeline::BODY_ENTER) { - print "\n"; - } - else { - print "\n"; - } - - print "" - . ""; - - # Create Timeline - if ($submod == $Timeline::TL_ENTER) { - print "\n"; - } - else { - print "\n"; - } - print "" - . ""; - - # View Timeline - if (($submod == $Timeline::VIEW_FR) || ($submod == $Timeline::VIEW_MENU)) { - print "\n"; - } - else { - print "\n"; - } - - # Notes - print ""; - if ($::USE_NOTES == 1) { - print -"" - . "" - . "" - . "" - . "" - . "
\n"; - - Print::print_html_footer_tabs(); - return 0; -} - -sub body_enter { - Print::print_html_header("Enter Data to Make Body File"); - - my $i; - my %mnt2img; - - # Cycle through each image we read from fsmorgue - foreach $i (keys %Caseman::vol2mnt) { - next - unless ($Caseman::vol2cat{$i} eq "part"); - next - if ( ($Caseman::vol2ftype{$i} eq "swap") - || ($Caseman::vol2ftype{$i} eq "raw")); - $mnt2vol{"$Caseman::vol2mnt{$i}--$i"} = $i; - } - -# sort via parent volume, then starting location, and then mount point (which includes the name) - my @mnt = sort { - ($Caseman::vol2par{$mnt2vol{$a}} cmp $Caseman::vol2par{$mnt2vol{$b}}) - or ($Caseman::vol2start{$mnt2vol{$a}} <=> - $Caseman::vol2start{$mnt2vol{$b}}) - or (lc($a) cmp lc($b)) - } keys %mnt2vol; - - print "
\n" - . "\n" - . "\n" - . Args::make_hidden() - . "

Here we will process the file system images, collect the temporal data, and save the data to a single file." - . "

1. Select one or more of the following images to collect data from:\n" - . ""; - - for (my $i = 0; $i <= $#mnt; $i++) { - my $vol = $mnt2vol{$mnt[$i]}; - - print "" - . "\n"; - } - - print "
" - . "$Caseman::vol2mnt{$vol}$Caseman::vol2sname{$vol}$Caseman::vol2ftype{$vol}

2. Select the data types to gather:
\n" - . "" - . "" - . "" - . "
" - . "Allocated Files" - . "Unallocated Files
\n" - . "

3. Enter name of output file (body):
" - . "$::DATADIR/" - . "\n" - . "\n" - . "

4. Generate MD5 Value? " - . ""; - - print "

\n"; - - Print::print_html_footer(); - return 0; -} - -sub body_run { - Args::check_fname(); - Args::check_fname_mode(); - Print::print_html_header("Make Body File"); - - my $fname_rel = Args::get_fname_rel(); - my $fname = Args::get_fname(); - - my $fname_mode = $Args::args{'fname_mode'}; - - if ((-e "$fname") && ($FNAME_MODE_INIT == $fname_mode)) { - print "File Already Exists: $fname_rel\n"; - - my $hidden = Args::make_hidden(); - - $hidden .= - "\n" - . "\n"; - - my $i; - foreach $i (%Caseman::vol2mnt) { - $hidden .= "\n" - if (exists $Args::args{$i}); - } - - $hidden .= - "\n" - if (exists $Args::args{'al_file'}); - $hidden .= - "\n" - if (exists $Args::args{'unal_file'}); - $hidden .= - "\n" - if (exists $Args::args{'md5'}); - - # Make a new name - print "
\n" - . "New Name: " - . "\n"; - - # Overwrite it - print "
" - . "\n" - . "$hidden" - . "\n" - . "
\n" - . "
\n" - . "\n" - . "\n" - . "$hidden" - . "
"; - - return 0; - } - - # we will be appending to the file so we should del it now - if (-e "$fname") { - unlink($fname); - } - - my $log_files = ""; - my $log_type = ""; - - # What kind of data are we collecting? - my $al_file = 0; - if (exists $Args::args{'al_file'}) { - $al_file = $Args::args{'al_file'}; - $log_type .= "Allocated Files"; - } - - my $unal_file = 0; - if (exists $Args::args{'unal_file'}) { - $unal_file = $Args::args{'unal_file'}; - $log_type .= ", " if ($log_type ne ""); - $log_type .= "Unallocated Files"; - } - - if (($unal_file == 0) && ($al_file == 0)) { - print - "No data types were selected. You must select at least one.
\n"; - return 1; - } - - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - my $i; - my $found = 0; - local *OUT; - - # Analyze each image - the image names are passed as an argument - foreach $i (keys %Caseman::vol2mnt) { - if (exists $Args::args{$i}) { - - $found = 1; - my $ftype = $Caseman::vol2ftype{$i}; - my $img = $Caseman::vol2path{$i}; - my $offset = $Caseman::vol2start{$i}; - my $imgtype = $Caseman::vol2itype{$i}; - my $mnt = $Caseman::vol2mnt{$i}; - - $log_files .= ", " if ($log_files ne ""); - $log_files .= "$i"; - - if (($al_file) && ($unal_file)) { - print "Running fls -r -m on $i
\n"; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/fls' $tz -s $Caseman::ts -m '$mnt' -f $ftype -r -o $offset -i $imgtype $img >> '$fname'" - ); - print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - } - elsif ($al_file) { - print "Running fls -ru -m on $i
\n"; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/fls' $tz -s $Caseman::ts -m '$mnt' -f $ftype -ru -o $offset -i $imgtype $img >> '$fname'" - ); - print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - } - elsif ($unal_file) { - print "Running fls -rd -m on $i
\n"; - Exec::exec_pipe(*OUT, -"'$::TSKDIR/fls' $tz -s $Caseman::ts -m '$mnt' -f $ftype -rd -o $offset -i $imgtype $img >> '$fname'" - ); - print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - } - } - } - - unless ($found) { - print -"No images were given for analysis. At least one must be selected.
\n"; - return 1; - } - - Print::log_host_inv( - "Saving timeline data for $log_type for $log_files to $fname_rel"); - - # append to host config - my $bod_vol = Caseman::add_vol_host_config("body", $fname_rel); - $Caseman::vol2cat{$bod_vol} = "timeline"; - $Caseman::vol2ftype{$bod_vol} = "body"; - $Caseman::vol2itype{$bod_vol} = "raw"; - $Caseman::vol2path{$bod_vol} = $fname; - $Caseman::vol2start{$bod_vol} = 0; - $Caseman::vol2end{$bod_vol} = 0; - $Caseman::vol2sname{$bod_vol} = $fname_rel; - - print "
Body file saved to $fname

\n" - . "Entry added to host config file

\n"; - - # Calculate MD5 - if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { - print "Calculating MD5 Value

\n"; - my $m = Hash::int_create_wrap($bod_vol); - print "MD5 Value: $m

\n"; - } - - print "

The next step is to sort the data into a timeline." - . "

\n" - . "\n" - . "\n" - . "\n" - . "\n" - . Args::make_hidden() - . "\n
\n"; - - Print::print_html_footer(); - return 0; -} - -my $OTYPE_NORM = 1; -my $OTYPE_HOURLY = 2; -my $OTYPE_DAILY = 3; - -sub tl_enter { - Print::print_html_header("Enter data for timeline"); - - my @body; - - # Find the body files if we will be looking for them - unless ((exists $Args::args{'body'}) - && (exists $Caseman::vol2cat{$Args::args{'body'}})) - { - foreach my $k (keys %Caseman::vol2cat) { - if ( ($Caseman::vol2cat{$k} eq "timeline") - && ($Caseman::vol2ftype{$k} eq "body")) - { - push @body, $k; - } - } - - if (scalar(@body) == 0) { - print "There are currently no body files " - . "for this host.
You must create the intermediate " - . "data file before you can perform this step
\n" - . "

" - . "\"Ok\"" - . "\n"; - return 1; - } - } - print "Now we will sort the data and save it to a timeline.

\n" - . "

\n" - . "\n" - . "\n" - . Args::make_hidden() - . "1. Select the data input file (body):\n" - . ""; - - # if the body file was specified then just print it - if (exists $Args::args{'body'}) { - print "\n"; - } - else { - my @body_sort = sort { lc($a) cmp lc($b) } @body; - my $chk = " CHECKED"; - for (my $i = 0; $i <= $#body_sort; $i++) { - print "\n"; - $chk = ""; - } - } - - my $cur_mon = 1 + (localtime())[4]; - my $cur_year = 1900 + (localtime())[5]; - - # STARTING DATE - print "
" - . "$Caseman::vol2sname{$Args::args{'body'}}
$Caseman::vol2sname{$body_sort[$i]}
\n" - . "

2. Enter the starting date:
\n" - . "None:
" - . "Specify: " - . "" - . "" - . "\n"; - - # END DATE - print "

3. Enter the ending date:
\n" - . "None:
\n" - . "Specify: \n" - . "\n" - . "" - . "\n"; - - # FILE NAME - print "

4. Enter the file name to save as:
" - . "$::DATADIR/
\n" - . "\n"; - - # Get only the UNIX images - since only they have /etc/passwd and group - my @unix_imgs; - my $root_vol = ""; - foreach my $i (keys %Caseman::vol2ftype) { - my $f = $Caseman::vol2ftype{$i}; - - next - unless (($f =~ /^ext/) - || ($f =~ /^ufs/) - || ($f =~ /^linux/) - || ($f =~ /bsd$/) - || ($f =~ /^solaris$/) - || ($f =~ /^bsdi$/)); - - push @unix_vols, $i; - - # Keep a reference to an image with '/' as the mounting point - $root_vol = $i - if ($Caseman::vol2mnt{$i} eq '/'); - } - - my $cnt = 5; - if (scalar @unix_vols > 0) { - - print -"

$cnt. Select the UNIX image that contains the /etc/passwd and /etc/group files:
\n"; - $cnt++; - - print "\n"; - } - - print "

$cnt. Choose the output format:
\n"; - $cnt++; - print -"  Tabulated (normal)
\n" - . "  Comma delimited with hourly summary
\n" - . "  Comma delimited with daily summary
\n"; - - print "

$cnt. Generate MD5 Value? "; - $cnt++; - - print "\n"; - - # Create Button - print "

\n

\n"; - - Print::print_html_footer(); - return 0; -} - -sub tl_run { - Args::check_fname(); - Args::check_body(); - Args::check_sort(); - - Print::print_html_header("Make Timeline"); - - my $body = Args::get_body(); - my $fname = Args::get_fname(); - my $fname_rel = Args::get_fname_rel(); - my $otype = Args::get_sort(); - - my $fname_mode = $Args::args{'fname_mode'}; - - if ((-e "$fname") && ($FNAME_MODE_INIT == $fname_mode)) { - print "File Already Exists: $fname_rel
\n"; - - my $hidden = - "" - . Args::make_hidden(); - - $hidden .= - "\n" - if (exists $Args::args{'st_none'}); - $hidden .= - "\n" - if (exists $Args::args{'st_year'}); - $hidden .= - "\n" - if (exists $Args::args{'st_day'}); - $hidden .= - "\n" - if (exists $Args::args{'st_mon'}); - $hidden .= - "\n" - if (exists $Args::args{'end_none'}); - $hidden .= - "\n" - if (exists $Args::args{'end_year'}); - $hidden .= - "\n" - if (exists $Args::args{'end_day'}); - $hidden .= - "\n" - if (exists $Args::args{'end_mon'}); - $hidden .= - "\n" - if (exists $Args::args{'tz'}); - $hidden .= - "\n" - if (exists $Args::args{'pw_vol'}); - $hidden .= - "\n" - if (exists $Args::args{'md5'}); - $hidden .= - "\n" - if (exists $Args::args{'sort'}); - - # Make a new name - print "
\n" - . "New Name: " - . "\n"; - - # Overwrite it - print "
" - . "\n" - . "\n" - . "\n" - . "$hidden\n" - . "\n" - . "
\n" - . "
\n" - . "\n" - . "\n" - . "\n" - . "\n" . "$hidden\n" . "
"; - - return 0; - } - - my $mon; - my $day; - my $year; - - my $date = ""; - - # Get the start date - unless ((exists $Args::args{'st_none'}) && ($Args::args{'st_none'} == 1)) { - - if (exists $Args::args{'st_mon'}) { - Args::check_st_mon(); - $mon = Args::get_st_mon(); - if (($mon < 1) || ($mon > 12)) { - print("Invalid starting month\n"); - return 1; - } - if ($mon < 10) { - $mon = "0" . $mon; - } - } - if (exists $Args::args{'st_year'}) { - Args::check_st_year(); - $year = Args::get_st_year(); - if (($year < 1970) || ($year > 2020)) { - print("Invalid starting year\n"); - return 1; - } - } - if ( (exists $Args::args{'st_day'}) - && ($Args::args{'st_day'} =~ /^(\d\d?)$/)) - { - $day = $1; - if (($day < 1) || ($day > 31)) { - print("Invalid starting day\n"); - return 1; - } - if ($day < 10) { - $day = "0" . $day; - } - } - else { - print("Invalid start day\n"); - return 1; - } - - $date = "$year-$mon-$day"; - } - - unless ((exists $Args::args{'end_none'}) && ($Args::args{'end_none'} == 1)) - { - - if ($date eq "") { - print "Begin date must be given if ending date is given
"; - return 1; - } - - if ( (exists $Args::args{'end_mon'}) - && ($Args::args{'end_mon'} =~ /^(\d\d?)$/)) - { - $mon = $1; - if (($mon < 1) || ($mon > 12)) { - print("Invalid end month\n"); - return 1; - } - if ($mon < 10) { - $mon = "0" . $mon; - } - } - else { - print("Invalid end month\n"); - return 1; - } - if ( (exists $Args::args{'end_year'}) - && ($Args::args{'end_year'} =~ /^(\d\d\d\d)$/)) - { - $year = $1; - if (($year < 1970) || ($year > 2020)) { - print("Invalid ending year\n"); - return 1; - } - - } - else { - print("Invalid end year\n"); - return 1; - } - if ( (exists $Args::args{'end_day'}) - && ($Args::args{'end_day'} =~ /^(\d\d?)$/)) - { - $day = $1; - if (($day < 1) || ($day > 31)) { - print("Invalid end day\n"); - return 1; - } - if ($day < 10) { - $day = "0" . $day; - } - } - else { - print("Invalid end day\n"); - return 1; - } - - $date .= "..$year-$mon-$day"; - } - - # temp strings for the password and group files - my $pw_tmp = ""; - my $gr_tmp = ""; - my $mac_args = ""; - my $log = ""; - - local *OUT; - - # Password and Group Files - if ((exists $Args::args{'pw_vol'}) && ($Args::args{'pw_vol'} ne "")) { - Args::check_vol('pw_vol'); - my $pw_vol = Args::get_vol('pw_vol'); - - my $ftype = $Caseman::vol2ftype{$pw_vol}; - my $img = $Caseman::vol2path{$pw_vol}; - my $offset = $Caseman::vol2start{$pw_vol}; - my $imgtype = $Caseman::vol2itype{$pw_vol}; - - $log .= "Password & Group File ($pw_vol) "; - - # Get the passwd file meta and copy the file - Exec::exec_pipe(*OUT, -"'$::TSKDIR/ifind' -f $ftype -n 'etc/passwd' -o $offset -i $imgtype $img" - ); - my $pwi = Exec::read_pipe_line(*OUT); - close(OUT); - - $pwi = "Error getting meta for passwd" - if ((!defined $pwi) || ($pwi eq "")); - - # Do the Taint Checking - if ($pwi =~ /^($::REG_META)$/) { - $pwi = $1; - - $log .= "Password Meta Address ($pwi) "; - - # Find a temp name that we can call it - my $i; - for ($i = 0;; $i++) { - unless (-e "$fname.pw-$i") { - $pw_tmp = "$fname.pw-$i"; - last; - } - } - - Exec::exec_sys( -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $pwi > '$pw_tmp'" - ); - $mac_args .= " -p \'$pw_tmp\' "; - - } - else { - print( -"Error finding /etc/passwd meta in $Caseman::vol2sname{$pw_vol} ($pwi)
" - ); - Print::log_host_inv( -"$Caseman::vol2sname{$pw_vol}: /etc/passwd file not found for timeline" - ); - } - - # Get the group file meta and copy the file - Exec::exec_pipe(*OUT, -"'$::TSKDIR/ifind' -f $ftype -n 'etc/group' -o $offset -i $imgtype $img" - ); - my $gri = Exec::read_pipe_line(*OUT); - close(OUT); - - $gri = "Error getting meta for group" - if ((!defined $gri) || ($gri eq "")); - - # Do the Taint Checking - if ($gri =~ /^($::REG_META)$/) { - $gri = $1; - - $log .= "Group Meta Address ($gri) "; - - # Find a temp name that we can call it - my $i; - for ($i = 0;; $i++) { - unless (-e "$fname.gr-$i") { - $gr_tmp = "$fname.gr-$i"; - last; - } - } - Exec::exec_sys( -"'$::TSKDIR/icat' -f $ftype -o $offset -i $imgtype $img $gri > '$gr_tmp'" - ); - $mac_args .= " -g \'$gr_tmp\' "; - } - else { - print( -"Error finding /etc/group meta in $Caseman::vol2sname{$pw_vol} ($gri)
" - ); - Print::log_host_inv( -"$Caseman::vol2sname{$pw_vol}: /etc/group file not found for timeline" - ); - } - } - - if ($date eq "") { - print - "Creating Timeline using all dates (Time Zone: $Caseman::tz)
\n"; - Print::log_host_inv( -"$Caseman::vol2sname{$body}: Creating timeline using all dates (TZ: $Caseman::tz) ${log}to $fname_rel" - ); - } - else { - print "Creating Timeline for $date (Time Zone: $Caseman::tz)
\n"; - Print::log_host_inv( -"$Caseman::vol2sname{$body}: Creating timeline for $date (TZ: $Caseman::tz) ${log}to $fname_rel" - ); - } - - my $tz = ""; - $tz = "-z '$Caseman::tz'" unless ("$Caseman::tz" eq ""); - - # mactime needs the path to run the 'date' command - $ENV{PATH} = "/bin:/usr/bin"; - local *OUT; - if ($otype == $OTYPE_NORM) { - Exec::exec_pipe(*OUT, -"LANG=C LC_ALL=C '$::TSKDIR/mactime' -b $Caseman::vol2path{$body} $tz -i day '${fname}.sum' $mac_args $date > '$fname'" - ); - } - elsif ($otype == $OTYPE_HOURLY) { - Exec::exec_pipe(*OUT, -"LANG=C LC_ALL=C '$::TSKDIR/mactime' -b $Caseman::vol2path{$body} $tz -d -i hour '${fname}.sum' $mac_args $date > '$fname'" - ); - } - elsif ($otype == $OTYPE_DAILY) { - Exec::exec_pipe(*OUT, -"LANG=C LC_ALL=C '$::TSKDIR/mactime' -b $Caseman::vol2path{$body} $tz -d -i day '${fname}.sum' $mac_args $date > '$fname'" - ); - } - else { - Print::print_err("Unknown output type"); - } - - print "$_
\n" while ($_ = Exec::read_pipe_line(*OUT)); - close(OUT); - $ENV{PATH} = ""; - - # Remove the password and group files - unlink("$pw_tmp") if ($pw_tmp ne ""); - unlink("$gr_tmp") if ($gr_tmp ne ""); - - print "
Timeline saved to $fname

\n"; - - # append to fsmorgue if a normal timeline - if ($otype == $OTYPE_NORM) { - my $tl_vol = Caseman::add_vol_host_config("timeline", $fname_rel); - print "Entry added to host config file

\n"; - - $Caseman::vol2cat{$tl_vol} = "timeline"; - $Caseman::vol2ftype{$tl_vol} = "timeline"; - $Caseman::vol2itype{$tl_vol} = "raw"; - $Caseman::vol2path{$tl_vol} = "$fname"; - $Caseman::vol2start{$tl_vol} = 0; - $Caseman::vol2end{$tl_vol} = 0; - $Caseman::vol2sname{$tl_vol} = $fname_rel; - - # Calculate MD5 - if ((exists $Args::args{'md5'}) && ($Args::args{'md5'} == 1)) { - print "Calculating MD5 Value

\n"; - my $m = Hash::int_create_wrap($tl_vol); - print "MD5 Value: $m

\n"; - } - - print "
\n" - . "\n" - . "\n" - . "\n" - . "\n" - . Args::make_hidden() - . "\n
\n" - . "(NOTE: It is easier to view the timeline in a text editor than here)"; - } - else { - print - "Comma delimited files cannot be viewed from within Autopsy.
\n" - . "Open it in a spreadsheet or other data processing tool.
\n"; - } - Print::print_html_footer(); - return 0; -} - -sub view_menu { - Print::print_html_header("View Timeline Menu"); - - my @tl; - - # Find the timelines in the images hash - foreach my $k (keys %Caseman::vol2cat) { - if ( ($Caseman::vol2cat{$k} eq "timeline") - && ($Caseman::vol2ftype{$k} eq "timeline")) - { - push @tl, $k; - } - } - - if (scalar(@tl) == 0) { - print "There are currently no timeline files in the " - . "host config file.
One must first be created before you " - . "can view it
\n"; - - print "

" - . "\"Ok\"" - . "\n"; - - return 1; - } - - print "

\n" - . "\n" - . "\n" - . Args::make_hidden() - . "1. Select the timeline file:\n" - . "\n"; - - my @tl_sort = sort { lc($a) cmp lc($b) } @tl; - for (my $i = 0; $i <= $#tl_sort; $i++) { - print "\n"; - } - - print "
$Caseman::vol2sname{$tl_sort[$i]}
\n" - . "\n
\n"; - - Print::print_html_footer(); - return 0; -} - -sub view_fr { - Args::check_tl(); - - Print::print_html_header_frameset(""); - my $tl_vol = Args::get_tl(); - my $tl = $Caseman::vol2path{$tl_vol}; - my $url = ""; - - unless (exists $Args::args{'st_mon'}) { - - unless (open(TL, $tl)) { - print("Error opening $tl"); - return (1); - } - - my $beg_mon; - my $beg_year; - my $cnt = 0; - while () { - $cnt++; - if (/^(?:\w\w\w )?(\w\w\w)\s+\d\d\s+(\d\d\d\d)\s+\d\d:\d\d:\d\d/) { - $url = "tl=$tl_vol&st_mon=$::m2d{$1}&st_year=$2"; - - } - last; - } - close(TL); - - if ($cnt == 0) { - print "Empty timeline
\n"; - return 1; - } - if ($url eq "") { - print "Invalid Timeline
\n"; - return 1; - } - } - else { - $url = - "tl=$tl_vol&st_mon=$Args::enc_args{'st_mon'}&" - . "st_year=$Args::enc_args{'st_year'}"; - } - - print "\n" - . "\n" - . "\n"; - - Print::print_html_footer(); - return 0; -} - -sub view_idx { - Args::check_st_mon(); - Args::check_st_year(); - Args::check_tl(); - - Print::print_html_header("View Timeline Index"); - - my $mon = Args::get_st_mon(); - my $year = Args::get_st_year(); - my $tl_vol = Args::get_tl(); - my $tl = $Caseman::vol2path{$tl_vol}; - - print "
"; - my $url = - "$::PROGNAME?$Args::baseargs&mod=$::MOD_TL&view=$Timeline::VIEW_FR&" - . "tl=$tl_vol"; - - # Next and Previous pointers - my $pyear = $year; - my $pmon = $mon - 1; - if ($pmon == 0) { - $pmon = 12; - $pyear--; - } - print "\n" - . "\n" - . "\n"; - - if (-e "${tl}.sum") { - print "\n" - . "\n"; - } - - my $nyear = $year; - my $nmon = $mon + 1; - if ($nmon == 13) { - $nmon = 1; - $nyear++; - } - - print "
" - . "" - . "<- $::d2m[$pmon] $pyear " - . "Summary " - . "" - . "$::d2m[$nmon] $nyear ->
\n"; - - # Make a form to enter the next month and year to show. - # it defaults to the current location - print "
\n" - . "\n" - . "\n" - . "\n" - . Args::make_hidden() - . - - "\n" - . "" - . "" - . "\n" - . "
" - . "" - . "" - . "
\n"; - - Print::print_html_footer(); - return 0; -} - -# Display the contents of the summary file (hits per day) and show -# it as hits per month -sub view_sum { - Args::check_tl(); - - Print::print_html_header("View Timeline Summary"); - - my $tl_vol = Args::get_tl(); - my $tl = $Caseman::vol2path{$tl_vol}; - - $tl .= ".sum"; - - open(TL, "<$tl") or die "Can not open $tl"; - my $url = - "$::PROGNAME?$Args::baseargs&mod=$::MOD_TL&" - . "view=$Timeline::VIEW_FR&tl=$tl_vol"; - - print "

This page provides a monthly summary of activity.
" - . "Each day that has activity is noted with the number of events
\n"; - - my $p_year = ""; - my $p_mon = ""; - - print "

\n"; - - while () { - my @a = split(/ /, $_); - next unless (scalar(@a) == 5); - my $mon = $::m2d{$a[1]}; - my $year = $a[3]; - $year = $1 if ($year =~ /^(\d{4,4}):$/); - - if (($p_year ne $year) || ($p_mon ne $mon)) { - print "\n"; - - $p_year = $year; - $p_mon = $mon; - } - print "" - . "\n"; - } - print "
" - . "" - . "$a[1] $year
  $a[0]$a[1]$a[2]$year($a[4])
\n"; - - close(TL); - - Print::print_html_footer(); - return 0; -} - -# display a given month of the timeline -sub view { - Args::check_tl(); - Args::check_st_mon(); - Args::check_st_year(); - - my $tl_vol = Args::get_tl(); - my $tl = $Caseman::vol2path{$tl_vol}; - my $st_mon = Args::get_st_mon(); - my $st_year = Args::get_st_year(); - - Print::print_html_header("View $st_mon, $st_year of Timeline"); - - unless (open(TL, "$tl")) { - print("Error opening $tl"); - return (1); - } - - Print::log_host_inv( - "$Args::args{'tl'}: Viewing timeline for $::d2m[$st_mon] $st_year"); - - print "\n"; - - # zone identifies if we should be printing or not - my $zone = 0; - my $row = 0; - while () { - if ( -/^(?:(\w\w\w\s+)?(\w\w\w\s+\d\d\s+\d\d\d\d)\s+(\d\d:\d\d:\d\d))?\s+(\d+)\s+([macb\.]+)\s+([-\/\?\w]+)\s+([\d\w\/]+)\s+([\d\w\/]+)\s+($::REG_META)\s+(.*)$/o - ) - { - - my $day = ""; - $day = $1 if (defined $1); - my $date = ""; - $date = $2 if (defined $2); - my $time = ""; - $time = $3 if (defined $3); - my $sz = $4; - my $mac = $5; - my $p = $6; - my $u = $7; - my $g = $8; - my $i = $9; - my $f = $10; - - # we must break this down to see if we can skip it or not - if ($date ne "") { - if ($date =~ /^(\w\w\w)\s+\d\d\s+(\d\d\d\d)$/) { - if ($2 < $st_year) { - next; - } - elsif (($2 == $st_year) && ($::m2d{$1} < $st_mon)) { - next; - } - elsif ($2 > $st_year) { - last; - } - elsif (($2 == $st_year) && ($::m2d{$1} > $st_mon)) { - last; - } - else { - $zone = 1; - } - } - } - - # we need to print this entry - if ($zone) { - - # the deleted meta entries screw up in HTML - $f = "<$1 >" if ($f =~ /^<(.*?)>$/); - - if (($row % 2) == 0) { - print "\n"; - } - else { - print - "\n"; - } - - print "" - . "" - . "\n"; - - $row++; - } - } - else { - print "Error parsing timeline: " - . Print::html_encode($_) - . "
\n"; - } - } - close(TL); - print "
$day $date $time$sz$mac$p$u$g$i" - . Print::html_encode($f) - . "
"; - - Print::print_html_footer(); - return 0; -} - -# Blank Page -sub blank { - Print::print_html_header(""); - print "

File Activity Timelines

\n" - . "Here you can create a timeline of file activity.
\n" - . "This process requires two steps:

\n" - . "1. Create Data File from file system data  ->" - . "  2. Create Timeline from the data file\n" - . "

Use the tabs above to start.\n"; - Print::print_html_footer(); - return 0; -} diff --git a/lib/Vs.pm b/lib/Vs.pm deleted file mode 100644 index 2ce43f3fb0..0000000000 --- a/lib/Vs.pm +++ /dev/null @@ -1,8 +0,0 @@ -package Vs; - -# These need to be updated as The Sleuth Kit supports more volume systems -$Vs::type{'dos'} = 1; -$Vs::type{'bsd'} = 1; -$Vs::type{'gpt'} = 1; -$Vs::type{'mac'} = 1; -$Vs::type{'sun'} = 1; diff --git a/lib/define.pl b/lib/define.pl deleted file mode 100644 index 9bce1fa805..0000000000 --- a/lib/define.pl +++ /dev/null @@ -1,39 +0,0 @@ -# -$VER = '2.24'; - -$HTTP_NL = "\x0a"; -$notes_file = ""; - -$PICTDIR = "$INSTALLDIR/pict/"; -$SANITIZE_TAG = 'AutopsySanitized'; -$SANITIZE_PICT = 'sanitized.jpg'; - -$PROGNAME = 'autopsy'; - -# Default directory names -$MKDIR_MASK = 0775; -$IMGDIR = 'images'; -$DATADIR = 'output'; -$LOGDIR = 'logs'; -$REPDIR = 'reports'; - -# Colors -$BACK_COLOR = "#CCCC99"; -$BACK_COLOR_TABLE = "#CCCCCC"; -$DEL_COLOR[0] = "red"; -$DEL_COLOR[1] = "#800000"; # used when meta data structure has been reallocated -$NORM_COLOR = ""; -$LINK_COLOR = "blue"; - -$YEL_PIX = "pict/back_pix.jpg"; - -%m2d = ( - "Jan", 1, "Feb", 2, "Mar", 3, "Apr", 4, "May", 5, "Jun", 6, - "Jul", 7, "Aug", 8, "Sep", 9, "Oct", 10, "Nov", 11, "Dec", 12 -); -@d2m = ( - "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", - "Aug", "Sep", "Oct", "Nov", "Dec" -); - -1; diff --git a/lib/search.pl b/lib/search.pl deleted file mode 100644 index 4ea1b363d1..0000000000 --- a/lib/search.pl +++ /dev/null @@ -1,51 +0,0 @@ -# -# This file contains pre-defined search strings. A button for each will -# be displayed in the Search Mode. -# -# The $auto_srch{} hash is filled in with the search string -# The index into the hash is the name of the search. -# -# For example, $auto_srch{'foo'} = "bar"; would search for the string -# bar -# -# If the search is case sensitive, then set $auto_srch_csense to 1 (this -# is the default value if not specified. Set to 0 for insensitive -# -# If the search is a regular expression, set $auto_srch_reg to 1, else -# 0 (the default) -# -# -# If you develop patterns that you think will be useful to others, email -# them to me and I will include them in the next version (carrier@sleuthkit.org) -# - -# Date / syslog search of month and date -$auto_srch{'Date'} = -"((jan)|(feb)|(mar)|(apr)|(may)|(june?)|(july?)|(aug)|(sept?)|(oct)|(nov)|(dec))([[:space:]]+[[:digit:]])?"; -$auto_srch_reg{'Date'} = 1; -$auto_srch_csense{'Date'} = 0; - -# IP Address -$auto_srch{'IP'} = -'[0-2]?[[:digit:]]{1,2}\.[0-2]?[[:digit:]]{1,2}\.[0-2]?[[:digit:]]{1,2}\.[0-2]?[[:digit:]]{1,2}'; -$auto_srch_reg{'IP'} = 1; -$auto_srch_csense{'IP'} = 0; - -# SSN in the pattern of 123-12-1234 - from Jerry Shenk -$auto_srch{'SSN1'} = '[0-9][0-9][0-9]\-[0-9]]0-9]\-[0-9][0-9][0-9][0-9]'; -$auto_srch_reg{'SSN1'} = 1; -$auto_srch_csense{'SSN1'} = 0; - -# SSN in the pattern of 123121234 - from Jerry Shenk -$auto_srch{'SSN2'} = '[0-9][0-9][0-9][0-9]]0-9][0-9][0-9][0-9][0-9]'; -$auto_srch_reg{'SSN2'} = 1; -$auto_srch_csense{'SSN2'} = 0; - -# CC # - from Jerry Shenk -$auto_srch{'CC'} = - '[0-9][0-9][0-9][0-9]]0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]]0-9]'; -$auto_srch_reg{'CC'} = 1; -$auto_srch_csense{'CC'} = 0; - -# This must be the last value -1; diff --git a/man/man1/autopsy.1 b/man/man1/autopsy.1 deleted file mode 100755 index 39f983d6a7..0000000000 --- a/man/man1/autopsy.1 +++ /dev/null @@ -1,163 +0,0 @@ -.TH AUTOPSY 1 "MAR 2005" "User Manuals" -.SH NAME -autopsy \- Autopsy Forensic Browser -.SH SYNOPSIS -.B autopsy [-c] [-C] [-d -.I evid_locker -.B ] [-i -device filesystem mnt -.B ] [-p -.I port -.B ] -.I [addr] -.SH DESCRIPTION -By default, -.B autopsy -starts the Autopsy Forensic Browser server on port 9999 and and accepts -connections from the localhost. If -.I -p port -is given, then the server opens on that port and if -.I addr -is given, then connections are only accepted from that host. -When the -.I -i -argument is given, then autopsy goes into live analysis mode. - -The arguments are as follows: -.IP "-c" -Force the program to use cookies even for localhost. -.IP "-C" -Force the program to not use cookies even for remote hosts. -.IP "-d evid_locker" -Directory where cases and hosts are stored. -This overrides the -.B LOCKDIR -value in -.I conf.pl. -The path must be a full path (i.e. start with /). -.IP "-i device filesystem mnt" -Specify the information for the live analysis mode. This can be specified -as many times as needed. The -.I device -field is for the raw file system device, the -.I filesystem -field is for the file system type, and the -.I mnt -field is for the mounting point of the file system. -.IP "-p port" -TCP port for server to listen on. -.IP addr -IP address or host name of where investigator is located. -If localhost is used, then 'localhost' must be used in the URL. -If you use the actual hostname or IP, it will be rejected. -.PP -When started, the program will display a URL to paste into an -HTML browser. The browser must support frames and forms. The -Autopsy Forensic Browser will allow an investigator to analyze -images generated by -.BR dd(1) -for evidence. The program allows the images to be analyzed by -browsing files, blocks, inodes, or by searching the blocks. -The program also generates Autopsy reports that include collection -time, investigators name, and MD5 hash values. -.SH VARIABLES -The following variables can be set in -.I conf.pl. - -.I USE_STIMEOUT -.RS -When set to 1 (default is 0), the server will exit after -.B STIMEOUT -seconds of inactivity (default is 3600). This setting is recommended if -cookies are not used. -.RE -.I BASEDIR -.RS -Directory where cases and forensic images are located. -The images must have simple -names with only letters, numbers, '_', '-', and '.'. (See FILES). -.RE -.I TSKDIR -.RS -Directory where The Sleuth Kit binaries are located. -.RE -.I NSRLDB -.RS -Location of the NIST National Software Reference Library (NSRL). -.RE -.I INSTALLDIR -.RS -Directory where Autopsy was installed. -.RE -.I GREP_EXE -.RS -Location of -.BR grep(1) -binary. -.RE -.I STRINGS_EXE -.RS -Location of -.BR strings(1) -binary. -.RE -.SH FILES -.I Evidence Locker -.RS -The Evidence Locker is where all cases and hosts will be saved to. It -is a directory that will have a directory for each case. Each case -directory will have a directory for each host. - -.RE -.I /case.aut -.RS -This file is the case configuration file for the case. It contains the -description of the case and default subdirectories for the hosts. - -.RE -.I /investigators.txt -.RS -This file contains the list of investigators that will use this case. These -are used for logging only, not authentication. - -.RE -.I /host.aut -.RS -This file is where the host configuration details are saved. It -is similar to the 'fsmorgue' file from previous versions of Autopsy. -It has an entry for each file in the host and contains the host -description. - - -.RE -.I md5.txt -.RS -Some directories will have this file in it. It contains MD5 values for -important files in the directory. This makes it easy to validate the -integrity of images. - -.SH EXAMPLE -# ./autopsy -p 8888 10.1.34.19 -.SH "SEE ALSO" -.BR dd (1), -.BR fls (1), -.BR ffind (1), -.BR ifind (1), -.BR grep (1), -.BR icat (1) -.BR md5 (1), -.BR strings (1), -.SH REQUIREMENTS -The Autopsy Forensic Browser requires -.B The Sleuth Kit - - -.SH HISTORY -.BR "autopsy" " first appeared in " "Autopsy" " v1.0." -.SH LICENSE -This software is distributed under the GNU Public License. - -.SH AUTHOR -Brian Carrier - -Send documentation updates to diff --git a/pict/back_pix.jpg b/pict/back_pix.jpg deleted file mode 100644 index 1a5da64c9b..0000000000 Binary files a/pict/back_pix.jpg and /dev/null differ diff --git a/pict/but_addnote.jpg b/pict/but_addnote.jpg deleted file mode 100644 index 0946f296f4..0000000000 Binary files a/pict/but_addnote.jpg and /dev/null differ diff --git a/pict/but_alloc_list.jpg b/pict/but_alloc_list.jpg deleted file mode 100644 index 525fd081f3..0000000000 Binary files a/pict/but_alloc_list.jpg and /dev/null differ diff --git a/pict/but_export.jpg b/pict/but_export.jpg deleted file mode 100644 index 4cbc75a024..0000000000 Binary files a/pict/but_export.jpg and /dev/null differ diff --git a/pict/but_force.jpg b/pict/but_force.jpg deleted file mode 100644 index 2a92475c71..0000000000 Binary files a/pict/but_force.jpg and /dev/null differ diff --git a/pict/but_indexdb.jpg b/pict/but_indexdb.jpg deleted file mode 100644 index 5e51b78054..0000000000 Binary files a/pict/but_indexdb.jpg and /dev/null differ diff --git a/pict/but_lookup.jpg b/pict/but_lookup.jpg deleted file mode 100644 index b6bd6daf9f..0000000000 Binary files a/pict/but_lookup.jpg and /dev/null differ diff --git a/pict/but_new_name.jpg b/pict/but_new_name.jpg deleted file mode 100644 index 5a24bb42ea..0000000000 Binary files a/pict/but_new_name.jpg and /dev/null differ diff --git a/pict/but_next.jpg b/pict/but_next.jpg deleted file mode 100644 index c5639baeb5..0000000000 Binary files a/pict/but_next.jpg and /dev/null differ diff --git a/pict/but_ok.jpg b/pict/but_ok.jpg deleted file mode 100644 index 3bb2996fa2..0000000000 Binary files a/pict/but_ok.jpg and /dev/null differ diff --git a/pict/but_prev.jpg b/pict/but_prev.jpg deleted file mode 100644 index 46c4f39700..0000000000 Binary files a/pict/but_prev.jpg and /dev/null differ diff --git a/pict/but_replace.jpg b/pict/but_replace.jpg deleted file mode 100644 index 0c17557a59..0000000000 Binary files a/pict/but_replace.jpg and /dev/null differ diff --git a/pict/but_report.jpg b/pict/but_report.jpg deleted file mode 100644 index e283c36212..0000000000 Binary files a/pict/but_report.jpg and /dev/null differ diff --git a/pict/but_search.jpg b/pict/but_search.jpg deleted file mode 100644 index ed5287e349..0000000000 Binary files a/pict/but_search.jpg and /dev/null differ diff --git a/pict/but_view.jpg b/pict/but_view.jpg deleted file mode 100644 index 90a0ae9b60..0000000000 Binary files a/pict/but_view.jpg and /dev/null differ diff --git a/pict/but_viewcont.jpg b/pict/but_viewcont.jpg deleted file mode 100644 index 76f58842ee..0000000000 Binary files a/pict/but_viewcont.jpg and /dev/null differ diff --git a/pict/favicon.ico b/pict/favicon.ico deleted file mode 100644 index 0a4ba44527..0000000000 Binary files a/pict/favicon.ico and /dev/null differ diff --git a/pict/file_b_alldel.jpg b/pict/file_b_alldel.jpg deleted file mode 100644 index e82f225ddd..0000000000 Binary files a/pict/file_b_alldel.jpg and /dev/null differ diff --git a/pict/file_b_allfiles.jpg b/pict/file_b_allfiles.jpg deleted file mode 100644 index ac88e0c271..0000000000 Binary files a/pict/file_b_allfiles.jpg and /dev/null differ diff --git a/pict/file_b_check.jpg b/pict/file_b_check.jpg deleted file mode 100644 index 68049e674a..0000000000 Binary files a/pict/file_b_check.jpg and /dev/null differ diff --git a/pict/file_b_expand.jpg b/pict/file_b_expand.jpg deleted file mode 100644 index 86b720efa5..0000000000 Binary files a/pict/file_b_expand.jpg and /dev/null differ diff --git a/pict/file_b_hide.jpg b/pict/file_b_hide.jpg deleted file mode 100644 index 5689c05b18..0000000000 Binary files a/pict/file_b_hide.jpg and /dev/null differ diff --git a/pict/file_b_md5list.jpg b/pict/file_b_md5list.jpg deleted file mode 100644 index 9dac25518a..0000000000 Binary files a/pict/file_b_md5list.jpg and /dev/null differ diff --git a/pict/file_h_acc_cur.jpg b/pict/file_h_acc_cur.jpg deleted file mode 100644 index 8907e17b7b..0000000000 Binary files a/pict/file_h_acc_cur.jpg and /dev/null differ diff --git a/pict/file_h_acc_link.jpg b/pict/file_h_acc_link.jpg deleted file mode 100644 index 50d9ca2a32..0000000000 Binary files a/pict/file_h_acc_link.jpg and /dev/null differ diff --git a/pict/file_h_chg_cur.jpg b/pict/file_h_chg_cur.jpg deleted file mode 100644 index 0f987ce883..0000000000 Binary files a/pict/file_h_chg_cur.jpg and /dev/null differ diff --git a/pict/file_h_chg_link.jpg b/pict/file_h_chg_link.jpg deleted file mode 100644 index 8dab273e0c..0000000000 Binary files a/pict/file_h_chg_link.jpg and /dev/null differ diff --git a/pict/file_h_cre_cur.jpg b/pict/file_h_cre_cur.jpg deleted file mode 100644 index 0df3fc9a0e..0000000000 Binary files a/pict/file_h_cre_cur.jpg and /dev/null differ diff --git a/pict/file_h_cre_link.jpg b/pict/file_h_cre_link.jpg deleted file mode 100644 index 3861f661ef..0000000000 Binary files a/pict/file_h_cre_link.jpg and /dev/null differ diff --git a/pict/file_h_del_cur.jpg b/pict/file_h_del_cur.jpg deleted file mode 100644 index 38a713b9ab..0000000000 Binary files a/pict/file_h_del_cur.jpg and /dev/null differ diff --git a/pict/file_h_del_link.jpg b/pict/file_h_del_link.jpg deleted file mode 100644 index 253db16e8c..0000000000 Binary files a/pict/file_h_del_link.jpg and /dev/null differ diff --git a/pict/file_h_gid_cur.jpg b/pict/file_h_gid_cur.jpg deleted file mode 100644 index e775b344bd..0000000000 Binary files a/pict/file_h_gid_cur.jpg and /dev/null differ diff --git a/pict/file_h_gid_link.jpg b/pict/file_h_gid_link.jpg deleted file mode 100644 index 3883362809..0000000000 Binary files a/pict/file_h_gid_link.jpg and /dev/null differ diff --git a/pict/file_h_meta_cur.jpg b/pict/file_h_meta_cur.jpg deleted file mode 100644 index 62d64d95d7..0000000000 Binary files a/pict/file_h_meta_cur.jpg and /dev/null differ diff --git a/pict/file_h_meta_link.jpg b/pict/file_h_meta_link.jpg deleted file mode 100644 index d691cfe273..0000000000 Binary files a/pict/file_h_meta_link.jpg and /dev/null differ diff --git a/pict/file_h_mod_cur.jpg b/pict/file_h_mod_cur.jpg deleted file mode 100644 index f08924e959..0000000000 Binary files a/pict/file_h_mod_cur.jpg and /dev/null differ diff --git a/pict/file_h_mod_link.jpg b/pict/file_h_mod_link.jpg deleted file mode 100644 index a6e7aabfe9..0000000000 Binary files a/pict/file_h_mod_link.jpg and /dev/null differ diff --git a/pict/file_h_nam_cur.jpg b/pict/file_h_nam_cur.jpg deleted file mode 100644 index 19c3d43d63..0000000000 Binary files a/pict/file_h_nam_cur.jpg and /dev/null differ diff --git a/pict/file_h_nam_link.jpg b/pict/file_h_nam_link.jpg deleted file mode 100644 index 76c9de71e7..0000000000 Binary files a/pict/file_h_nam_link.jpg and /dev/null differ diff --git a/pict/file_h_siz_cur.jpg b/pict/file_h_siz_cur.jpg deleted file mode 100644 index 17b4fadaa9..0000000000 Binary files a/pict/file_h_siz_cur.jpg and /dev/null differ diff --git a/pict/file_h_siz_link.jpg b/pict/file_h_siz_link.jpg deleted file mode 100644 index 27527d69a2..0000000000 Binary files a/pict/file_h_siz_link.jpg and /dev/null differ diff --git a/pict/file_h_uid_cur.jpg b/pict/file_h_uid_cur.jpg deleted file mode 100644 index fa1d27ea31..0000000000 Binary files a/pict/file_h_uid_cur.jpg and /dev/null differ diff --git a/pict/file_h_uid_link.jpg b/pict/file_h_uid_link.jpg deleted file mode 100644 index 29bab9c18f..0000000000 Binary files a/pict/file_h_uid_link.jpg and /dev/null differ diff --git a/pict/file_h_wr_cur.jpg b/pict/file_h_wr_cur.jpg deleted file mode 100644 index bd9d380ed7..0000000000 Binary files a/pict/file_h_wr_cur.jpg and /dev/null differ diff --git a/pict/file_h_wr_link.jpg b/pict/file_h_wr_link.jpg deleted file mode 100644 index 709726d663..0000000000 Binary files a/pict/file_h_wr_link.jpg and /dev/null differ diff --git a/pict/hashdb_h_alert.jpg b/pict/hashdb_h_alert.jpg deleted file mode 100644 index 55301aacd7..0000000000 Binary files a/pict/hashdb_h_alert.jpg and /dev/null differ diff --git a/pict/hashdb_h_ig.jpg b/pict/hashdb_h_ig.jpg deleted file mode 100644 index edf80bbadc..0000000000 Binary files a/pict/hashdb_h_ig.jpg and /dev/null differ diff --git a/pict/hashdb_h_nsrl.jpg b/pict/hashdb_h_nsrl.jpg deleted file mode 100644 index b333af90c1..0000000000 Binary files a/pict/hashdb_h_nsrl.jpg and /dev/null differ diff --git a/pict/int_b_calc.jpg b/pict/int_b_calc.jpg deleted file mode 100644 index db33eca6ba..0000000000 Binary files a/pict/int_b_calc.jpg and /dev/null differ diff --git a/pict/int_b_valid.jpg b/pict/int_b_valid.jpg deleted file mode 100644 index aee869b6e6..0000000000 Binary files a/pict/int_b_valid.jpg and /dev/null differ diff --git a/pict/int_h_data.jpg b/pict/int_h_data.jpg deleted file mode 100644 index cf69f3704e..0000000000 Binary files a/pict/int_h_data.jpg and /dev/null differ diff --git a/pict/int_h_img.jpg b/pict/int_h_img.jpg deleted file mode 100644 index a22cf45eee..0000000000 Binary files a/pict/int_h_img.jpg and /dev/null differ diff --git a/pict/int_h_str.jpg b/pict/int_h_str.jpg deleted file mode 100644 index f8b3e8e751..0000000000 Binary files a/pict/int_h_str.jpg and /dev/null differ diff --git a/pict/int_h_tl.jpg b/pict/int_h_tl.jpg deleted file mode 100644 index d1afeed84e..0000000000 Binary files a/pict/int_h_tl.jpg and /dev/null differ diff --git a/pict/int_h_unalloc.jpg b/pict/int_h_unalloc.jpg deleted file mode 100644 index ce7fa58139..0000000000 Binary files a/pict/int_h_unalloc.jpg and /dev/null differ diff --git a/pict/logo.jpg b/pict/logo.jpg deleted file mode 100644 index 0d9c29c382..0000000000 Binary files a/pict/logo.jpg and /dev/null differ diff --git a/pict/main_t_dat_cur.jpg b/pict/main_t_dat_cur.jpg deleted file mode 100644 index 02bf5442e8..0000000000 Binary files a/pict/main_t_dat_cur.jpg and /dev/null differ diff --git a/pict/main_t_dat_link.jpg b/pict/main_t_dat_link.jpg deleted file mode 100644 index e40990093d..0000000000 Binary files a/pict/main_t_dat_link.jpg and /dev/null differ diff --git a/pict/main_t_fil_cur.jpg b/pict/main_t_fil_cur.jpg deleted file mode 100644 index 91a4a83e20..0000000000 Binary files a/pict/main_t_fil_cur.jpg and /dev/null differ diff --git a/pict/main_t_fil_link.jpg b/pict/main_t_fil_link.jpg deleted file mode 100644 index 82b814c7d6..0000000000 Binary files a/pict/main_t_fil_link.jpg and /dev/null differ diff --git a/pict/main_t_fil_org.jpg b/pict/main_t_fil_org.jpg deleted file mode 100644 index 150bdb4962..0000000000 Binary files a/pict/main_t_fil_org.jpg and /dev/null differ diff --git a/pict/main_t_ftype_cur.jpg b/pict/main_t_ftype_cur.jpg deleted file mode 100644 index c72918d7f8..0000000000 Binary files a/pict/main_t_ftype_cur.jpg and /dev/null differ diff --git a/pict/main_t_ftype_link.jpg b/pict/main_t_ftype_link.jpg deleted file mode 100644 index 9161ec5fdc..0000000000 Binary files a/pict/main_t_ftype_link.jpg and /dev/null differ diff --git a/pict/main_t_ftype_org.jpg b/pict/main_t_ftype_org.jpg deleted file mode 100644 index 801c1b075a..0000000000 Binary files a/pict/main_t_ftype_org.jpg and /dev/null differ diff --git a/pict/main_t_img_cur.jpg b/pict/main_t_img_cur.jpg deleted file mode 100644 index 5de656e4a6..0000000000 Binary files a/pict/main_t_img_cur.jpg and /dev/null differ diff --git a/pict/main_t_img_link.jpg b/pict/main_t_img_link.jpg deleted file mode 100644 index 51c1654dfb..0000000000 Binary files a/pict/main_t_img_link.jpg and /dev/null differ diff --git a/pict/main_t_img_org.jpg b/pict/main_t_img_org.jpg deleted file mode 100644 index bdc0d29355..0000000000 Binary files a/pict/main_t_img_org.jpg and /dev/null differ diff --git a/pict/main_t_met_cur.jpg b/pict/main_t_met_cur.jpg deleted file mode 100644 index 64016bdeca..0000000000 Binary files a/pict/main_t_met_cur.jpg and /dev/null differ diff --git a/pict/main_t_met_link.jpg b/pict/main_t_met_link.jpg deleted file mode 100644 index cfe4494153..0000000000 Binary files a/pict/main_t_met_link.jpg and /dev/null differ diff --git a/pict/main_t_met_org.jpg b/pict/main_t_met_org.jpg deleted file mode 100644 index e5c014064d..0000000000 Binary files a/pict/main_t_met_org.jpg and /dev/null differ diff --git a/pict/main_t_srch_cur.jpg b/pict/main_t_srch_cur.jpg deleted file mode 100644 index 9b99415c84..0000000000 Binary files a/pict/main_t_srch_cur.jpg and /dev/null differ diff --git a/pict/main_t_srch_link.jpg b/pict/main_t_srch_link.jpg deleted file mode 100644 index 8087c4a48b..0000000000 Binary files a/pict/main_t_srch_link.jpg and /dev/null differ diff --git a/pict/menu_b_add.jpg b/pict/menu_b_add.jpg deleted file mode 100644 index 9a50a3c0b1..0000000000 Binary files a/pict/menu_b_add.jpg and /dev/null differ diff --git a/pict/menu_b_analyze.jpg b/pict/menu_b_analyze.jpg deleted file mode 100644 index ab8cad7400..0000000000 Binary files a/pict/menu_b_analyze.jpg and /dev/null differ diff --git a/pict/menu_b_back.jpg b/pict/menu_b_back.jpg deleted file mode 100644 index d424333163..0000000000 Binary files a/pict/menu_b_back.jpg and /dev/null differ diff --git a/pict/menu_b_cancel.jpg b/pict/menu_b_cancel.jpg deleted file mode 100644 index 1e0de235f7..0000000000 Binary files a/pict/menu_b_cancel.jpg and /dev/null differ diff --git a/pict/menu_b_ccls.jpg b/pict/menu_b_ccls.jpg deleted file mode 100644 index 879bcd5372..0000000000 Binary files a/pict/menu_b_ccls.jpg and /dev/null differ diff --git a/pict/menu_b_close.jpg b/pict/menu_b_close.jpg deleted file mode 100644 index ebed7dd19b..0000000000 Binary files a/pict/menu_b_close.jpg and /dev/null differ diff --git a/pict/menu_b_cnew.jpg b/pict/menu_b_cnew.jpg deleted file mode 100644 index f4fbf24758..0000000000 Binary files a/pict/menu_b_cnew.jpg and /dev/null differ diff --git a/pict/menu_b_copen.jpg b/pict/menu_b_copen.jpg deleted file mode 100644 index 4df3f4771b..0000000000 Binary files a/pict/menu_b_copen.jpg and /dev/null differ diff --git a/pict/menu_b_fs.jpg b/pict/menu_b_fs.jpg deleted file mode 100644 index 32bcd63cee..0000000000 Binary files a/pict/menu_b_fs.jpg and /dev/null differ diff --git a/pict/menu_b_hashdb.jpg b/pict/menu_b_hashdb.jpg deleted file mode 100644 index ffd2a995d0..0000000000 Binary files a/pict/menu_b_hashdb.jpg and /dev/null differ diff --git a/pict/menu_b_hcls.jpg b/pict/menu_b_hcls.jpg deleted file mode 100644 index 6ef9ec634a..0000000000 Binary files a/pict/menu_b_hcls.jpg and /dev/null differ diff --git a/pict/menu_b_help.jpg b/pict/menu_b_help.jpg deleted file mode 100644 index 6a0d06591a..0000000000 Binary files a/pict/menu_b_help.jpg and /dev/null differ diff --git a/pict/menu_b_hnew.jpg b/pict/menu_b_hnew.jpg deleted file mode 100644 index 8cf2e8c5ab..0000000000 Binary files a/pict/menu_b_hnew.jpg and /dev/null differ diff --git a/pict/menu_b_ifnew.jpg b/pict/menu_b_ifnew.jpg deleted file mode 100644 index ec8355f99b..0000000000 Binary files a/pict/menu_b_ifnew.jpg and /dev/null differ diff --git a/pict/menu_b_inew.jpg b/pict/menu_b_inew.jpg deleted file mode 100644 index 8f990e32d8..0000000000 Binary files a/pict/menu_b_inew.jpg and /dev/null differ diff --git a/pict/menu_b_int.jpg b/pict/menu_b_int.jpg deleted file mode 100644 index 5fc0af2521..0000000000 Binary files a/pict/menu_b_int.jpg and /dev/null differ diff --git a/pict/menu_b_menu.jpg b/pict/menu_b_menu.jpg deleted file mode 100644 index 124a7e0980..0000000000 Binary files a/pict/menu_b_menu.jpg and /dev/null differ diff --git a/pict/menu_b_next.jpg b/pict/menu_b_next.jpg deleted file mode 100644 index c1f2c254ff..0000000000 Binary files a/pict/menu_b_next.jpg and /dev/null differ diff --git a/pict/menu_b_note.jpg b/pict/menu_b_note.jpg deleted file mode 100644 index eeea7bb101..0000000000 Binary files a/pict/menu_b_note.jpg and /dev/null differ diff --git a/pict/menu_b_ok.jpg b/pict/menu_b_ok.jpg deleted file mode 100644 index e682233fb4..0000000000 Binary files a/pict/menu_b_ok.jpg and /dev/null differ diff --git a/pict/menu_b_ref.jpg b/pict/menu_b_ref.jpg deleted file mode 100644 index a7a4329df9..0000000000 Binary files a/pict/menu_b_ref.jpg and /dev/null differ diff --git a/pict/menu_b_rem.jpg b/pict/menu_b_rem.jpg deleted file mode 100644 index 0a6f73498d..0000000000 Binary files a/pict/menu_b_rem.jpg and /dev/null differ diff --git a/pict/menu_b_seq.jpg b/pict/menu_b_seq.jpg deleted file mode 100644 index d903d25a19..0000000000 Binary files a/pict/menu_b_seq.jpg and /dev/null differ diff --git a/pict/menu_b_tl.jpg b/pict/menu_b_tl.jpg deleted file mode 100644 index 212be616c4..0000000000 Binary files a/pict/menu_b_tl.jpg and /dev/null differ diff --git a/pict/menu_h_cdet.jpg b/pict/menu_h_cdet.jpg deleted file mode 100644 index b9bcfa77e4..0000000000 Binary files a/pict/menu_h_cdet.jpg and /dev/null differ diff --git a/pict/menu_h_cnew.jpg b/pict/menu_h_cnew.jpg deleted file mode 100644 index 9488016824..0000000000 Binary files a/pict/menu_h_cnew.jpg and /dev/null differ diff --git a/pict/menu_h_hdet.jpg b/pict/menu_h_hdet.jpg deleted file mode 100644 index 55d96bb1ce..0000000000 Binary files a/pict/menu_h_hdet.jpg and /dev/null differ diff --git a/pict/menu_h_hnew.jpg b/pict/menu_h_hnew.jpg deleted file mode 100644 index a0293ccd5c..0000000000 Binary files a/pict/menu_h_hnew.jpg and /dev/null differ diff --git a/pict/menu_h_idet.jpg b/pict/menu_h_idet.jpg deleted file mode 100644 index dff892fa72..0000000000 Binary files a/pict/menu_h_idet.jpg and /dev/null differ diff --git a/pict/menu_h_inew.jpg b/pict/menu_h_inew.jpg deleted file mode 100644 index 1671f20cc4..0000000000 Binary files a/pict/menu_h_inew.jpg and /dev/null differ diff --git a/pict/menu_t_cg_cur.jpg b/pict/menu_t_cg_cur.jpg deleted file mode 100644 index 4ace65321d..0000000000 Binary files a/pict/menu_t_cg_cur.jpg and /dev/null differ diff --git a/pict/menu_t_cg_link.jpg b/pict/menu_t_cg_link.jpg deleted file mode 100644 index 4f758b5cdd..0000000000 Binary files a/pict/menu_t_cg_link.jpg and /dev/null differ diff --git a/pict/menu_t_cg_org.jpg b/pict/menu_t_cg_org.jpg deleted file mode 100644 index 152db19967..0000000000 Binary files a/pict/menu_t_cg_org.jpg and /dev/null differ diff --git a/pict/menu_t_hg_cur.jpg b/pict/menu_t_hg_cur.jpg deleted file mode 100644 index 72cb1fbacd..0000000000 Binary files a/pict/menu_t_hg_cur.jpg and /dev/null differ diff --git a/pict/menu_t_hg_link.jpg b/pict/menu_t_hg_link.jpg deleted file mode 100644 index 97f79c8f3e..0000000000 Binary files a/pict/menu_t_hg_link.jpg and /dev/null differ diff --git a/pict/menu_t_hg_org.jpg b/pict/menu_t_hg_org.jpg deleted file mode 100644 index 37f4b11045..0000000000 Binary files a/pict/menu_t_hg_org.jpg and /dev/null differ diff --git a/pict/menu_t_hm_cur.jpg b/pict/menu_t_hm_cur.jpg deleted file mode 100644 index 67a9ee4699..0000000000 Binary files a/pict/menu_t_hm_cur.jpg and /dev/null differ diff --git a/pict/menu_t_hm_link.jpg b/pict/menu_t_hm_link.jpg deleted file mode 100644 index 4e17433ea4..0000000000 Binary files a/pict/menu_t_hm_link.jpg and /dev/null differ diff --git a/pict/menu_t_hm_org.jpg b/pict/menu_t_hm_org.jpg deleted file mode 100644 index 5fb204ae57..0000000000 Binary files a/pict/menu_t_hm_org.jpg and /dev/null differ diff --git a/pict/sanit_b_norm.jpg b/pict/sanit_b_norm.jpg deleted file mode 100644 index 2a86e0e6ae..0000000000 Binary files a/pict/sanit_b_norm.jpg and /dev/null differ diff --git a/pict/sanit_b_san.jpg b/pict/sanit_b_san.jpg deleted file mode 100644 index 601b8d67c0..0000000000 Binary files a/pict/sanit_b_san.jpg and /dev/null differ diff --git a/pict/sanitized.jpg b/pict/sanitized.jpg deleted file mode 100644 index bec0da750b..0000000000 Binary files a/pict/sanitized.jpg and /dev/null differ diff --git a/pict/srch_b_lorig.jpg b/pict/srch_b_lorig.jpg deleted file mode 100644 index 01354eec4e..0000000000 Binary files a/pict/srch_b_lorig.jpg and /dev/null differ diff --git a/pict/srch_b_lun.jpg b/pict/srch_b_lun.jpg deleted file mode 100644 index 8a2d2b720e..0000000000 Binary files a/pict/srch_b_lun.jpg and /dev/null differ diff --git a/pict/srch_b_str.jpg b/pict/srch_b_str.jpg deleted file mode 100644 index 9d9371452a..0000000000 Binary files a/pict/srch_b_str.jpg and /dev/null differ diff --git a/pict/srch_b_un.jpg b/pict/srch_b_un.jpg deleted file mode 100644 index e1a4b4d2da..0000000000 Binary files a/pict/srch_b_un.jpg and /dev/null differ diff --git a/pict/tab_close.jpg b/pict/tab_close.jpg deleted file mode 100644 index 0a63dd24ba..0000000000 Binary files a/pict/tab_close.jpg and /dev/null differ diff --git a/pict/tab_help.jpg b/pict/tab_help.jpg deleted file mode 100644 index 632e27006b..0000000000 Binary files a/pict/tab_help.jpg and /dev/null differ diff --git a/pict/tl_t_data_cur.jpg b/pict/tl_t_data_cur.jpg deleted file mode 100644 index d9d9b10638..0000000000 Binary files a/pict/tl_t_data_cur.jpg and /dev/null differ diff --git a/pict/tl_t_data_link.jpg b/pict/tl_t_data_link.jpg deleted file mode 100644 index fe8333bf27..0000000000 Binary files a/pict/tl_t_data_link.jpg and /dev/null differ diff --git a/pict/tl_t_notes_link.jpg b/pict/tl_t_notes_link.jpg deleted file mode 100644 index fe01d8c055..0000000000 Binary files a/pict/tl_t_notes_link.jpg and /dev/null differ diff --git a/pict/tl_t_notes_org.jpg b/pict/tl_t_notes_org.jpg deleted file mode 100644 index 03c643b84c..0000000000 Binary files a/pict/tl_t_notes_org.jpg and /dev/null differ diff --git a/pict/tl_t_tl_cur.jpg b/pict/tl_t_tl_cur.jpg deleted file mode 100644 index ed69d8bb25..0000000000 Binary files a/pict/tl_t_tl_cur.jpg and /dev/null differ diff --git a/pict/tl_t_tl_link.jpg b/pict/tl_t_tl_link.jpg deleted file mode 100644 index 1da8edd58d..0000000000 Binary files a/pict/tl_t_tl_link.jpg and /dev/null differ diff --git a/pict/tl_t_view_cur.jpg b/pict/tl_t_view_cur.jpg deleted file mode 100644 index b621d7d857..0000000000 Binary files a/pict/tl_t_view_cur.jpg and /dev/null differ diff --git a/pict/tl_t_view_link.jpg b/pict/tl_t_view_link.jpg deleted file mode 100644 index 9401607136..0000000000 Binary files a/pict/tl_t_view_link.jpg and /dev/null differ diff --git a/xcode/autopsy.xcodeproj/project.pbxproj b/xcode/autopsy.xcodeproj/project.pbxproj deleted file mode 100644 index f04caa4f2f..0000000000 --- a/xcode/autopsy.xcodeproj/project.pbxproj +++ /dev/null @@ -1,138 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 42; - objects = { - -/* Begin PBXFileReference section */ - 02B041C40E9070E400E46A87 /* .perltidyrc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = .perltidyrc; sourceTree = ""; }; - 02B041C50E9070E400E46A87 /* Appsort.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Appsort.pm; sourceTree = ""; }; - 02B041C60E9070E400E46A87 /* Appview.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Appview.pm; sourceTree = ""; }; - 02B041C70E9070E400E46A87 /* Args.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Args.pm; sourceTree = ""; }; - 02B041C80E9070E400E46A87 /* Caseman.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Caseman.pm; sourceTree = ""; }; - 02B041C90E9070E400E46A87 /* Data.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Data.pm; sourceTree = ""; }; - 02B041CA0E9070E400E46A87 /* define.pl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = define.pl; sourceTree = ""; }; - 02B041CB0E9070E400E46A87 /* Exec.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Exec.pm; sourceTree = ""; }; - 02B041CC0E9070E400E46A87 /* File.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = File.pm; sourceTree = ""; }; - 02B041CD0E9070E400E46A87 /* Filesystem.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Filesystem.pm; sourceTree = ""; }; - 02B041CE0E9070E400E46A87 /* Frame.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Frame.pm; sourceTree = ""; }; - 02B041CF0E9070E400E46A87 /* Fs.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Fs.pm; sourceTree = ""; }; - 02B041D00E9070E400E46A87 /* Hash.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Hash.pm; sourceTree = ""; }; - 02B041D10E9070E400E46A87 /* Kwsrch.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Kwsrch.pm; sourceTree = ""; }; - 02B041D20E9070E400E46A87 /* Main.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Main.pm; sourceTree = ""; }; - 02B041D30E9070E400E46A87 /* Meta.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Meta.pm; sourceTree = ""; }; - 02B041D40E9070E400E46A87 /* Notes.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Notes.pm; sourceTree = ""; }; - 02B041D50E9070E400E46A87 /* Print.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Print.pm; sourceTree = ""; }; - 02B041D60E9070E400E46A87 /* search.pl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = search.pl; sourceTree = ""; }; - 02B041D70E9070E400E46A87 /* Timeline.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Timeline.pm; sourceTree = ""; }; - 02B041D80E9070E400E46A87 /* Vs.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = Vs.pm; sourceTree = ""; }; - 02B041DA0E90710300E46A87 /* .perltidyrc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = .perltidyrc; sourceTree = ""; }; - 02B041DB0E90710300E46A87 /* autopsy.base */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = autopsy.base; sourceTree = ""; }; - 02B041DD0E90710400E46A87 /* make-live-cd.base */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "make-live-cd.base"; sourceTree = ""; }; - 02EF3BBF0860F668001CA8B0 /* global.css */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = global.css; path = ../global.css; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXGroup section */ - 02670C57079A2F7E00BA95F3 = { - isa = PBXGroup; - children = ( - 02B041D90E90710300E46A87 /* base */, - 02B041C30E9070E400E46A87 /* lib */, - 02EF3BBF0860F668001CA8B0 /* global.css */, - ); - sourceTree = ""; - }; - 02B041C30E9070E400E46A87 /* lib */ = { - isa = PBXGroup; - children = ( - 02B041C40E9070E400E46A87 /* .perltidyrc */, - 02B041C50E9070E400E46A87 /* Appsort.pm */, - 02B041C60E9070E400E46A87 /* Appview.pm */, - 02B041C70E9070E400E46A87 /* Args.pm */, - 02B041C80E9070E400E46A87 /* Caseman.pm */, - 02B041C90E9070E400E46A87 /* Data.pm */, - 02B041CA0E9070E400E46A87 /* define.pl */, - 02B041CB0E9070E400E46A87 /* Exec.pm */, - 02B041CC0E9070E400E46A87 /* File.pm */, - 02B041CD0E9070E400E46A87 /* Filesystem.pm */, - 02B041CE0E9070E400E46A87 /* Frame.pm */, - 02B041CF0E9070E400E46A87 /* Fs.pm */, - 02B041D00E9070E400E46A87 /* Hash.pm */, - 02B041D10E9070E400E46A87 /* Kwsrch.pm */, - 02B041D20E9070E400E46A87 /* Main.pm */, - 02B041D30E9070E400E46A87 /* Meta.pm */, - 02B041D40E9070E400E46A87 /* Notes.pm */, - 02B041D50E9070E400E46A87 /* Print.pm */, - 02B041D60E9070E400E46A87 /* search.pl */, - 02B041D70E9070E400E46A87 /* Timeline.pm */, - 02B041D80E9070E400E46A87 /* Vs.pm */, - ); - name = lib; - path = ../lib; - sourceTree = SOURCE_ROOT; - }; - 02B041D90E90710300E46A87 /* base */ = { - isa = PBXGroup; - children = ( - 02B041DA0E90710300E46A87 /* .perltidyrc */, - 02B041DB0E90710300E46A87 /* autopsy.base */, - 02B041DD0E90710400E46A87 /* make-live-cd.base */, - ); - name = base; - path = ../base; - sourceTree = SOURCE_ROOT; - }; -/* End PBXGroup section */ - -/* Begin PBXProject section */ - 02670C5B079A2F7E00BA95F3 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 027355510E7C4D6D002BD6DB /* Build configuration list for PBXProject "autopsy" */; - compatibilityVersion = "Xcode 2.4"; - hasScannedForEncodings = 1; - mainGroup = 02670C57079A2F7E00BA95F3; - projectDirPath = ""; - projectRoot = ""; - targets = ( - ); - }; -/* End PBXProject section */ - -/* Begin XCBuildConfiguration section */ - 027355520E7C4D6D002BD6DB /* Development */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Development; - }; - 027355530E7C4D6D002BD6DB /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Deployment; - }; - 027355540E7C4D6D002BD6DB /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Default; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 027355510E7C4D6D002BD6DB /* Build configuration list for PBXProject "autopsy" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 027355520E7C4D6D002BD6DB /* Development */, - 027355530E7C4D6D002BD6DB /* Deployment */, - 027355540E7C4D6D002BD6DB /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; -/* End XCConfigurationList section */ - }; - rootObject = 02670C5B079A2F7E00BA95F3 /* Project object */; -}