Cleaned up to make way for new version 3 code
340
COPYING
@ -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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
<signature of Ty Coon>, 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.
|
39
INSTALL.txt
@ -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]
|
||||
|
30
Makefile
@ -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
|
119
README-LIVE.txt
@ -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 <at> sleuthkit <dot> org]
|
58
TODO.txt
@ -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)
|
@ -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
|
@ -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, "</dev/urandom" or die "can not open /dev/urandom";
|
||||
read RAND, $r, 4;
|
||||
$magic = unpack "I", $r;
|
||||
read RAND, $r, 4;
|
||||
$magic .= unpack "I", $r;
|
||||
close RAND;
|
||||
}
|
||||
else {
|
||||
$magic = int(rand 0xffffffff) . int(rand 0xffffffff);
|
||||
}
|
||||
|
||||
$cookie_url = "$magic/";
|
||||
|
||||
# Save to file in case the stdout gets overwritten
|
||||
if ($SAVE_COOKIE == 1) {
|
||||
$cook_file = "$LOCKDIR/.$port.cookie";
|
||||
if (open COOK, ">$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 <<EOF;
|
||||
|
||||
============================================================================
|
||||
|
||||
Autopsy Forensic Browser
|
||||
http://www.sleuthkit.org/autopsy/
|
||||
ver $::VER
|
||||
|
||||
============================================================================
|
||||
EOF
|
||||
|
||||
if ($::LIVE == 0) {
|
||||
print "Evidence Locker: $LOCKDIR\n";
|
||||
}
|
||||
else {
|
||||
print "Live Analysis Mode\n";
|
||||
}
|
||||
if ($ispathclear == 0) {
|
||||
print
|
||||
"\nCYGWIN Mode (Internal path contains /bin, /usr/bin, and /usr/local/bin)\n\n";
|
||||
}
|
||||
|
||||
print <<EOF2;
|
||||
Start Time: $date
|
||||
Remote Host: $rema
|
||||
Local Port: $port
|
||||
|
||||
Open an HTML browser on the remote host and paste this URL in it:
|
||||
|
||||
http://$lclhost:${port}/${cookie_url}$::PROGNAME
|
||||
|
||||
Keep this process running and use <ctrl-c> 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"
|
||||
. "<html><center>\n"
|
||||
. "<h2>Access Denied</h2>\n"
|
||||
. "<h3>Your connection from: $ip has been logged</h3>\n"
|
||||
. "</center></html>$::HTTP_NL$::HTTP_NL$::HTTP_NL";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub bad_req {
|
||||
print "HTTP/1.0 404 Bad Request$::HTTP_NL"
|
||||
. "Content-type: text/html$::HTTP_NL$::HTTP_NL"
|
||||
. "<html><body><center>\n"
|
||||
. "<h2>Invalid URL<br><tt>"
|
||||
. shift()
|
||||
. "</tt></h2>\n"
|
||||
. "</center></body></html>"
|
||||
. "$::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 (<STDIN>) {
|
||||
|
||||
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 (<STDIN>) {
|
||||
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"
|
||||
. "<html>\n"
|
||||
. "<head><title>Error</title></head>\n"
|
||||
. "<h2><center>Unknown Extension</h2>\n"
|
||||
. "</center></html>$::HTTP_NL$::HTTP_NL$::HTTP_NL";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (<FILE>) {
|
||||
print "$_";
|
||||
}
|
||||
close(FILE);
|
||||
|
||||
print "$::HTTP_NL$::HTTP_NL";
|
||||
}
|
||||
else {
|
||||
print "HTTP/1.0 404 Bad Request$::HTTP_NL"
|
||||
. "Content-type: text/html$::HTTP_NL$::HTTP_NL"
|
||||
. "<html>\n"
|
||||
. "<head><title>Error</title></head>\n"
|
||||
. "<h2><center>File Not Found</h2>"
|
||||
. "</center></html>$::HTTP_NL$::HTTP_NL$::HTTP_NL";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub about {
|
||||
|
||||
print "HTTP/1.0 200 OK$::HTTP_NL"
|
||||
. "Content-type: text/html$::HTTP_NL$::HTTP_NL";
|
||||
|
||||
my $tskver = ::get_tskver();
|
||||
|
||||
print <<EOF;
|
||||
|
||||
<html>
|
||||
<head><title>About Autopsy</title></head>
|
||||
|
||||
<body BGCOLOR=#CCCC99>
|
||||
|
||||
<center><h2>About Autopsy</h2>
|
||||
<br>
|
||||
<img src=\"pict/logo.jpg\" alt=\"Logo\">
|
||||
<br><br>
|
||||
<b>Version</b>: $::VER
|
||||
<br>
|
||||
<tt><a href="http://www.sleuthkit.org/autopsy/">http://www.sleuthkit.org/autopsy/</a></tt>
|
||||
<br>
|
||||
<tt><a href="http://www.sleuthkit.org/informer/">http://www.sleuthkit.org/informer/</a></tt>
|
||||
</center>
|
||||
|
||||
|
||||
<h3>Credits</h3>
|
||||
<UL>
|
||||
<LI>Code Development: Brian Carrier (carrier at sleuthkit dot org)
|
||||
<LI>Interface Assistance: Samir Kapuria
|
||||
<LI>Mascot: Hash the Hound
|
||||
</UL>
|
||||
|
||||
<h3>Configuration</h3>
|
||||
<b>The Sleuth Kit</b>:<br>
|
||||
URL: <a href="http://www.sleuthkit.org/sleuthkit/">
|
||||
<tt>http://www.sleuthkit.org/sleuthkit/</tt></a><br>
|
||||
Installation Location: <tt>$::TSKDIR</tt><br>
|
||||
Version: $tskver<br>
|
||||
<b>Evidence Locker</b>: <tt>$LOCKDIR</tt><br>
|
||||
<b>grep</b>: <tt>$GREP_EXE</tt><br>
|
||||
<b>file</b>: <tt>$FILE_EXE</tt><br>
|
||||
<b><a href="http://www.nsrl.nist.gov/">NIST NSRL</a></b>: <tt>$NSRLDB</tt><br>
|
||||
|
||||
</body></html>
|
||||
|
||||
EOF
|
||||
return 0;
|
||||
}
|
||||
|
||||
### Check that the required tools are there
|
||||
sub check_tools {
|
||||
|
||||
# Sleuth Kit execs
|
||||
unless (-x $::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);
|
||||
}
|
||||
}
|
@ -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 (<AUT>) {
|
||||
$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 (<BASE>);
|
||||
|
||||
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";
|
475
configure
vendored
@ -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 ''
|
||||
|
@ -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
|
19
global.css
@ -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;
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Blank Page</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<p>
|
||||
|
||||
<p>
|
||||
|
||||
<p>
|
||||
<center>
|
||||
<h3>HELP!</h3>
|
||||
Here are the help files for using Autopsy.
|
||||
|
||||
<p>In addition to these files, the <tt>Sleuth Kit Informer</tt>
|
||||
newsletter could be useful.<br>
|
||||
The Informer typically goes into more technical details than what
|
||||
is provided here.</p>
|
||||
|
||||
<p><a href="http://www.sleuthkit.org/informer/" target=\"_blank\">
|
||||
http://www.sleuthkit.org/informer/</a></p>
|
||||
|
||||
<p>Send documentation updates to <doc-updates at sleuthkit dot org></p>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
@ -1,161 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Case Management Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
|
||||
<CENTER><H2>Case Management</H2></CENTER>
|
||||
<P>
|
||||
<H3>Overview</H3>
|
||||
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.
|
||||
|
||||
|
||||
<P>
|
||||
<H3>Creating a New Case</H3>
|
||||
From the Main Menu (at startup) select <U>New Case</U>. 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.
|
||||
|
||||
<P>
|
||||
For example:
|
||||
<TABLE CELLSPACING=8>
|
||||
<TR>
|
||||
<TD>Case Name:</TD><TD><TT>bankofmars</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Case Description:</TD><TD><TT>Theft of $1,000,000,000.01 from The Bank of Mars</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Investigators:</TD><TD><TT>gadget</TT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<P>
|
||||
<H3>Adding a New Host</H3>
|
||||
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 <U>Add Host</U> 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 <a href="timezones.html">here</a>.
|
||||
|
||||
<P>
|
||||
You can optionally add the path to <A HREF="hash_db.html">hash databases</A>.
|
||||
|
||||
<P>
|
||||
For example, the 'Bank of Mars' incident could have two hosts
|
||||
involved:
|
||||
|
||||
<TABLE CELLSPACING=8>
|
||||
<TR>
|
||||
<TD>Host Name:</TD><TD><TT>db_server</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Host Description:</TD><TD><TT>Main Database Server - Solaris</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Timezone:</TD><TD><TT>EST5EDT</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Timeskew:</TD><TD><TT>-100</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Known Good Database:</TD><TD><TT>none</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Known Bad Database:</TD><TD><TT>none</TT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<P>
|
||||
<TABLE CELLSPACING=8>
|
||||
<TR>
|
||||
<TD>Host Name:</TD><TD><TT>file_server</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Host Description:</TD><TD><TT>Windows File Server - Win 2k</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Timezone:</TD><TD><TT>CST6CDT</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Timeskew:</TD><TD><TT>0</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Known Good Database:</TD><TD><TT>/usr/local/forensics/hash/win2k.txt</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Known Bad Database:</TD><TD><TT>/usr/local/forensics/hash/win_hack.txt</TT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<P>
|
||||
<H3>Adding a New Image</H3>
|
||||
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
|
||||
<U>Add Image File</U> 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:
|
||||
|
||||
<TABLE CELLSPACING=8>
|
||||
<tr><td>Image Path:</TD><TD><TT>/mnt/sys1/disk2.*</TT></TD></TR>
|
||||
<tr><td>Type:</td><td><tt>Disk</tt></td></tr>
|
||||
<tr><td>Import Action:</TD><TD><TT>symlink</TT></TD></TR>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
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.
|
||||
|
||||
<p>
|
||||
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.
|
||||
|
||||
<P>
|
||||
<H3>MD5 Values</H3>
|
||||
Each host has an <TT>md5.txt</TT> 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.
|
||||
|
||||
|
||||
<P>
|
||||
<H3>Host Subdirectories</H3>
|
||||
Each host has an <TT>images</TT> directory and an <TT>output</TT>
|
||||
directory. All data generated by Autopsy is saved to the <TT>output</TT>
|
||||
directory. The theory behind this design, was to allow the <TT>images</TT>
|
||||
directory to have strict permissions to prevent accidently modifying
|
||||
the images. Therefore, the <TT>images</TT> directory can have its write
|
||||
bits removed to prevent modifications.
|
||||
|
||||
<p>
|
||||
<h3>References</h3>
|
||||
Issue 2 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The Sleuth Kit Informer</a> discusses case management and how to break a disk image into file system images.
|
||||
|
||||
|
||||
|
||||
<P><HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,97 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Data Unit Analysis Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
<CENTER><H2>Data Unit Analysis</H2></CENTER>
|
||||
|
||||
|
||||
<H3>Overview</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<H3>Input</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
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 <U>Image Details</U>)). Enter that
|
||||
address into the original text box and select the <U>Unallocated</U>
|
||||
type. This will find the original location and display it for you.
|
||||
|
||||
<P>
|
||||
If Autopsy knows about the 'blkls' image, then it can be loaded at any
|
||||
time by selecting the <U>Load Unallocated</U> button. Then, any
|
||||
data unit in that file can be examined.
|
||||
|
||||
|
||||
<P>
|
||||
The <B>Lazarus</B> tool was part of <TT>TCT</TT>. 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.
|
||||
|
||||
<P>
|
||||
Press the <U>Ok</U> button to display the contents of the address on
|
||||
the right-hand side of the window.
|
||||
|
||||
<P>
|
||||
The <U>Allocation List</U> link displays the allocation status of
|
||||
addresses in intervals of 500.
|
||||
|
||||
|
||||
<H3>Viewing</H3>
|
||||
<P>
|
||||
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).
|
||||
|
||||
<P>
|
||||
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
|
||||
<U>Export Contents</U> button. The <U>Add Note</U> button will allow
|
||||
one to add a comment about the given data unit so that it can be
|
||||
easily recalled later.
|
||||
|
||||
<P>
|
||||
The file type is also displayed. This is identified by running
|
||||
the output through the 'file' command in The Sleuth Kit.
|
||||
|
||||
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<H3>FAT Notes</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
|
||||
<P>
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,99 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy File Category Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>File Category Type Analysis Help</H2></CENTER>
|
||||
|
||||
<H3>Overview</H3>
|
||||
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.
|
||||
|
||||
<H3>Procedure</H3>
|
||||
The <TT>sorter</TT> document in the <TT>docs</TT> directory of The
|
||||
Sleuth Kit has more details on the details, but this will provide
|
||||
an overview of the interface given by Autopsy.
|
||||
|
||||
<P>
|
||||
The first step is to <U>Sort</U> the image. There are several
|
||||
options to choose when doing this. The <TT>sorter</TT> tool from
|
||||
The Sleuth Kit will perform the sorting. There are two major
|
||||
actions that <TT>sorter</TT> can do: sort files by type and validate
|
||||
extensions.
|
||||
|
||||
<P>
|
||||
By default, Autopsy will perform both actions. If you do not want
|
||||
it to do a given action, deselect it.
|
||||
|
||||
|
||||
<P>Within sorting, there are two options:
|
||||
|
||||
<UL>
|
||||
<LI> 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 <TT>images</TT> file. By selecting the <U>Save</U>
|
||||
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).
|
||||
|
||||
<LI> 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
|
||||
<TT>unknown</TT> file. If this is not desired, select the <U>Do Not
|
||||
Save Unknown</U> option.
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
During the sorting process, the <TT>sorter</TT> 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 <TT>mismatch</TT> file. This can be deselected if it is
|
||||
not wanted.
|
||||
|
||||
|
||||
<H3>Hash Databases</H3>
|
||||
One easy way of data reduction is to use hash databases. The <TT>sorter</TT>
|
||||
tool can use three different hash databases. Each can be configured
|
||||
within Autopsy and used in other screens.
|
||||
|
||||
<UL>
|
||||
<LI><B>NIST NSRL</B>: 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.
|
||||
|
||||
<LI><B>Ignore Database</B>: 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.
|
||||
|
||||
<LI><B>Alert Database</B>: 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 <TT>alert</TT> file.
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
More details can be found in the <A HREF="hash_db.html">Hash
|
||||
Database</A> Help.
|
||||
|
||||
<H3>Output</H3>
|
||||
Currently, there is no way to view the output from within Autopsy.
|
||||
All data can be found in the <TT>output</TT> directory of the host.
|
||||
A directory is created for the <TT>sorter</TT> output. View the
|
||||
<TT>index.html</TT> file and it contains links to the other files.
|
||||
|
||||
<p>
|
||||
<h3>References</h3>
|
||||
Issues 3, 4, and 5 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The
|
||||
Sleuth Kit Informer</a> discussed using the 'sorter' tool.
|
||||
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,221 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy File Analysis Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>File Analysis</H2></CENTER>
|
||||
<H3>Overview</H3>
|
||||
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.
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
|
||||
<H3>Directory List</H3>
|
||||
<P>
|
||||
The left-hand side window has four main options:
|
||||
<UL>
|
||||
<li>Directory Seek
|
||||
<li>File Name Search
|
||||
<LI>Hide / Expand Directories
|
||||
<LI>Show All Deleted Files
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
By default, the directory listing is not shown when this mode is
|
||||
first entered. By select the <U>Expand Directories</U> 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.
|
||||
|
||||
<P>
|
||||
Selecting the <U>All Deleted Files</U> link will display all of the deleted
|
||||
files in the image on the right-hand side.
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<p>
|
||||
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 "^\.".
|
||||
|
||||
|
||||
<H3>Directory Contents</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The column headers have the following definitions:
|
||||
<UL>
|
||||
<LI><B>del</B>: A check in this column represents a deleted file.
|
||||
See below for a discussion on the different color types of deleted files.
|
||||
|
||||
<LI><B>Type</B>: This column contains the "type" that the file or
|
||||
directory is. There are two values. The first (<TT>dir</TT>) is the
|
||||
type according to the directory entry structure. The directory entry
|
||||
is where the file name is located. The second value (<TT>in</TT>) 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.
|
||||
|
||||
<LI><B>Name</B>: 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.
|
||||
|
||||
<LI><B>Modified Time</B>: 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 <TT>utimes()</TT> function can modify this
|
||||
value vary easily.
|
||||
|
||||
<LI><B>Written Time</B>: 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.
|
||||
|
||||
<LI><B>Accessed Time</B>: 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.
|
||||
|
||||
<LI><B>Changed Time</B>: 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
|
||||
<TT>utimes()</TT> function in UNIX.
|
||||
|
||||
<LI><B>Created Time</B>: 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.
|
||||
|
||||
<LI><B>Size</B>: The size of the file. Note that if the size of the
|
||||
file is 0, no link will be shown with the name.
|
||||
|
||||
<LI><B>UID</B>: The User ID of the file owner.
|
||||
|
||||
<LI><B>GID</B>: The Group ID of the file owner.
|
||||
|
||||
<LI><B>Meta Data</B>: 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.
|
||||
|
||||
</UL>
|
||||
The <U>Add Note</U> link allows you to make a comment about this directory and
|
||||
have it saved in your personal notes file.
|
||||
|
||||
<P>
|
||||
The <U>Generate MD5 List</U>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The path on top of the window has hyperlinks in it that allow the
|
||||
user to easily change to a previous directory.
|
||||
|
||||
<P>
|
||||
There are two different colors used for deleted files. The difference
|
||||
is based on the status of the data structures in the file. A <FONT
|
||||
COLOR="red">bright red</FONT> 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 <FONT
|
||||
COLOR="#800000">darker red</FONT>, then the meta data
|
||||
structure has been reallocated and the data is most likely not
|
||||
accurate.
|
||||
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
To look a file up in one of the <A HREF="./hash_db.html">Hash
|
||||
Databases</A>, then select the meta data address. That view will
|
||||
provide an interface to the databases.
|
||||
|
||||
<H3>File Contents</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
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 <U>View</U> 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.
|
||||
|
||||
<P>
|
||||
The <U>Report</U> options create ASCII reports that contain the file
|
||||
contents as well as data such as MD5 values and dates.
|
||||
|
||||
<P>
|
||||
The <U>Export</U> button extracts the file out of the image so you can save it
|
||||
locally and use other tools on it.
|
||||
|
||||
<P>
|
||||
The <U>Add Note</U> button adds a personal note to the investigator log for
|
||||
future reference.
|
||||
|
||||
<p>
|
||||
<h3>References</h3>
|
||||
Issue 1 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The Sleuth
|
||||
Kit Informer</a>.
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,46 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Image Details Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>Image Details</H2></CENTER>
|
||||
|
||||
<P>
|
||||
<H3>Overview</H3>
|
||||
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.
|
||||
|
||||
<P>
|
||||
<H3>FFS & EXT2FS</H3>
|
||||
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.
|
||||
|
||||
|
||||
<P>
|
||||
<H3>FAT</H3>
|
||||
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 <A HREF="data_mode.html">data unit</A>
|
||||
analysis mode. Or, if the file is fragmented, the pointer can
|
||||
be selected and the screen will link to the next cluster chain.
|
||||
|
||||
|
||||
<P>
|
||||
<H3>NTFS</H3>
|
||||
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.
|
||||
|
||||
|
||||
<P>
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,103 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>General Autopsy Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>General Autopsy Help</H2></CENTER>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
All data are saved in a directory in the Evidence Locker, which
|
||||
was specified at install time or at run time. See
|
||||
<A HREF="caseman.html">Case Management</A>
|
||||
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.
|
||||
|
||||
|
||||
<P>
|
||||
The browser has the following modes:
|
||||
<UL>
|
||||
|
||||
<LI>
|
||||
<B><A HREF="file_mode.html">Files</A></B>:
|
||||
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.
|
||||
|
||||
<LI><B><A HREF="meta_mode.html">
|
||||
Meta Data</A></B>:
|
||||
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).
|
||||
|
||||
|
||||
<LI><B><A HREF="data_mode.html">
|
||||
Data Unit</A></B>:
|
||||
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 <I>strings(1)</I>.
|
||||
The meta data structure that has allocated the block will be
|
||||
displayed (if any) along with the file name (if any).
|
||||
|
||||
|
||||
<LI><B><A HREF="srch_mode.html">
|
||||
Keyword Search </A></B>:
|
||||
Search an image file using <I>grep(1)</I> 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.
|
||||
|
||||
|
||||
<LI><B><A HREF="fs_mode.html">
|
||||
Image Details</A></B>:
|
||||
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.
|
||||
|
||||
<LI><B><A HREF="int_mode.html">
|
||||
Image Integrity</A></B>:
|
||||
The integrity of the data can be validated at any
|
||||
point by selecting this mode. It uses the values in <TT>md5.txt</TT> to
|
||||
identify if any data have been modified in the analysis process.
|
||||
|
||||
<LI><B><A HREF="tl.html">
|
||||
File Activity Timelines</A></B>:
|
||||
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).
|
||||
|
||||
<LI><B><A HREF="file_category.html">
|
||||
File Type Categories</A></B>:
|
||||
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.
|
||||
|
||||
|
||||
<LI><B>Report Generation</B>:
|
||||
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.
|
||||
|
||||
</UL>
|
||||
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,70 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy grep Cheat Sheet</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>grep Cheat Sheet</H2></CENTER>
|
||||
|
||||
<H3>Escaped Values</H3>
|
||||
Autopsy uses the <TT>grep</TT> 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 <U>non-regular expression</U>. The escaped values include:
|
||||
<UL>
|
||||
<LI>\
|
||||
<LI>.
|
||||
<LI>[
|
||||
<LI>^
|
||||
<LI>$
|
||||
<LI>'
|
||||
<LI>*
|
||||
<LI>initial -
|
||||
</UL>
|
||||
|
||||
|
||||
<H3>Regular Expressions</H3>
|
||||
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:
|
||||
|
||||
<UL>
|
||||
<LI><B>[A-Za-z]</B>: Any lower and upper case letter
|
||||
<LI><B>[:alpha:]</B>: same as above
|
||||
<LI><B>[0-9]</B>: Any number
|
||||
<LI><B>[:digit:]</B>: same as above
|
||||
<LI><B>[0-9A-Za-z]</B>: Any lower and upper case letter or digit
|
||||
<LI><B>[:alnum:]</B>: same as above
|
||||
<LI><B>[:space:]</B>: Any white space
|
||||
</UL>
|
||||
|
||||
|
||||
<P>
|
||||
To specify how many times something can occur, the following are used:
|
||||
<UL>
|
||||
<LI><B>?</B>: Optional and can only occur once
|
||||
<LI><B>*</B>: Optional and can occur more than once
|
||||
<LI><B>+</B>: Required and can occur more than once
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
To specify more than one string to match, use the <B>|</B> operator.
|
||||
|
||||
<H3>Examples</H3>
|
||||
|
||||
<P>
|
||||
To search for 'Jane Smith' or 'Jack Smith': (Jane)|(Jack) Smith
|
||||
|
||||
<P>
|
||||
To ensure it matches if a tab is between the first and last name:
|
||||
(Jane)|(Jack)[:space:]Smith
|
||||
|
||||
<P>
|
||||
To search for 'Jane Smith' or 'Jane Anne Smith':
|
||||
Jane( Anne)? Smith
|
||||
|
||||
<P>
|
||||
or: Jane([:space:]Anne)?[:space:]Smith
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,75 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy grep Search Limitations</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2><TT>grep</TT> Search Limitations</H2></CENTER>
|
||||
|
||||
<H3>Overview</H3>
|
||||
<P>
|
||||
Keyword searches are very basic in Autopsy. Autopsy uses the
|
||||
<TT>strings</TT> and <TT>grep</TT> tools on the image and when a
|
||||
hit is found, it uses <TT>ifind</TT> and <TT>ffind</TT> 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.
|
||||
|
||||
<H3>What Will Be Found</H3>
|
||||
<TT>strings</TT> is first run on the image and the data is passed
|
||||
to <TT>grep</TT> 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.
|
||||
|
||||
<P>
|
||||
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 <TT>grep</TT>. 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.
|
||||
|
||||
<h3>What Will Be Found, but May Be Confusing</h3>
|
||||
<p>
|
||||
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 <tt>grep</tt> 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.
|
||||
|
||||
<H3>What Will NOT Be Found</H3>
|
||||
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 <TT>grep</TT>
|
||||
search would not find the string.
|
||||
|
||||
<P>
|
||||
Although not because of <TT>grep</TT>, Autopsy will also not find
|
||||
data in the slack space during an unallocated-only search. The
|
||||
extraction tool for The Sleuth Kit (<TT>blkls</TT>) 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.
|
||||
|
||||
|
||||
<H3>Conclusion</H3>
|
||||
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.
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,141 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Hash Database Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>Hash Database Help</H2></CENTER>
|
||||
|
||||
<H3>Overview</H3>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The <B>NIST National Software Reference Library (NSRL)</B> contains
|
||||
hashes of files that are found in operating systems and software
|
||||
distributions. These files are <I>known to be good</I> 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 <TT>www.nsrl.nist.gov</TT>.
|
||||
|
||||
<P>
|
||||
The <B>Ignore Database</B> is a database that the investigator must
|
||||
create. It is similar to the NIST NSRL in that it contains files
|
||||
that are <I>known to be good</I> and can be ignored if the user
|
||||
chooses to do so (only applicable when in <A HREF="file_category.html">File
|
||||
Type Category Analysis</A>). Examples of files in this category include
|
||||
system binaries for standard builds. See <A HREF="#db_create">Database
|
||||
Creation</A> for information on creating this database. Its location
|
||||
is configured when the host is created and can be edited in the
|
||||
host configuration file.
|
||||
|
||||
<P>
|
||||
The <B>Alert Database</B> is a database that the investigator must
|
||||
create. It contains hashes of <I>known bad</I> 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 <A HREF="file_category.html">File Type Category
|
||||
Analysis</A>, these files will be saved in a special file. See <A
|
||||
HREF="#db_create">Database Creation</A> for information on creating
|
||||
this database. Its location is configured when the host is created
|
||||
and can be edited in the host configuration file.
|
||||
|
||||
|
||||
<H3>Database Uses</H3>
|
||||
Autopsy uses the hash databases in three ways.
|
||||
|
||||
<UL>
|
||||
<LI><B><A HREF="file_category.html">File Type Category Analysis</A></B>: The
|
||||
hash databases are used to identify the <I>known bad</I> files and
|
||||
ignore the <I>known good</I> files.
|
||||
|
||||
<LI><B><A HREF="meta_mode.html">Meta Data Analysis</A></B>: 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.
|
||||
|
||||
<LI><B>Hash Database Manager</B>: 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.
|
||||
</UL>
|
||||
|
||||
|
||||
<A NAME="db_create">
|
||||
<H3>Database Creation</H3>
|
||||
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).
|
||||
|
||||
<P>
|
||||
Autopsy uses the <TT>hfind</TT> 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).
|
||||
|
||||
<P>
|
||||
The NIST NSRL obviously does not have to be created, but it does have
|
||||
to be indexed before it is used.
|
||||
|
||||
<P>
|
||||
To make a hash database, we will create a file with the same format
|
||||
as the <TT>md5sum</TT> command uses. This is just the MD5 hash,
|
||||
some white space, and the file name. For example:<BR>
|
||||
|
||||
<TT>c4a6761b486de3c6abf7cf2c554289e5
|
||||
/bin/ps</TT><P>
|
||||
|
||||
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:<BR>
|
||||
|
||||
<TT># md5sum /bin/* /sbin/* > bin-md5.db</TT><P>
|
||||
|
||||
After creation, hash databases must be indexed and sorted (this
|
||||
includes the NSRL). Databases will be indexed by using the
|
||||
<TT>hfind</TT> tool. The NSRL database would be indexed with:<BR>
|
||||
|
||||
<TT># hfind -i nsrl-md5 PATH_TO_NSRL/NSRLFile.txt</TT><P>
|
||||
|
||||
A database made by <TT>md5sum</TT> would be indexed with:<BR>
|
||||
|
||||
<TT># hfind -i md5sum bin-md5.db</TT><P>
|
||||
|
||||
Or, if Autopsy has this file configured from when the host was added,
|
||||
then it can be re-indexed from the Hash Database Manager.
|
||||
|
||||
<H3>Autopsy Configuration</H3>
|
||||
The alert and ignore databases are stored in the host configuration file
|
||||
with the headers of 'exclude_db' and 'alert_db'. For example:<BR>
|
||||
|
||||
<TT>alert_db '/usr/local/hash/bad.db'</TT><P>
|
||||
These entries can be edited at any time.
|
||||
|
||||
<P>
|
||||
The NSRL database is configured in the <TT>conf.pl</TT> file in the
|
||||
directory where Autopsy was installed. It has the $NSRLDB variable.
|
||||
For example:<BR>
|
||||
|
||||
<TT>$NSRLDB = '/usr/local/hash/nsrl/NSRLFile.txt';</TT><P>
|
||||
|
||||
It can be edited, added, and removed at any time (but you must restart
|
||||
Autopsy).
|
||||
|
||||
|
||||
<p>
|
||||
<h3>References</h3>
|
||||
Issues 6 and 7 of <a href="http://www.sleuthkit.org/informer/" target=\"_blank\">The
|
||||
Sleuth Kit Informer</a> discussed hash databases.
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,11 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Help</TITLE></HEAD>
|
||||
<LINK REL="SHORTCUT ICON" HREF="../pict/favicon.ico">
|
||||
<FRAMESET COLS="20%,*">
|
||||
|
||||
<FRAME SRC="menu.html">
|
||||
<FRAME SRC="blank.html" NAME="cont">
|
||||
|
||||
</FRAMESET>
|
||||
|
||||
</HTML>
|
@ -1,29 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Integrity Check Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>Integrity Check</H2></CENTER>
|
||||
|
||||
<H3>Overview</H3>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The <TT>md5.txt</TT> 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.
|
||||
|
||||
<P>
|
||||
When the <U>Image Integrity</U> button is selected from the <U>Host
|
||||
Manager</U> 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.
|
||||
|
||||
|
||||
<P>
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,37 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Help Topics</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<P><A HREF="general.html" TARGET="cont">General Information</A>
|
||||
|
||||
<P><A HREF="caseman.html" TARGET="cont">Case Management</A>
|
||||
|
||||
<HR>
|
||||
|
||||
<P><A HREF="file_mode.html" TARGET="cont">File Analysis</A>
|
||||
|
||||
<P><A HREF="meta_mode.html" TARGET="cont">Meta Data Analysis</A>
|
||||
|
||||
<P><A HREF="data_mode.html" TARGET="cont">Data Unit Analysis</A>
|
||||
|
||||
<P><A HREF="fs_mode.html" TARGET="cont">Image Details</A>
|
||||
|
||||
<P><A HREF="srch_mode.html" TARGET="cont">Keyword Searching</A>
|
||||
|
||||
<P><A HREF="grep.html" TARGET="cont">grep Cheat Sheet</A>
|
||||
|
||||
<P><A HREF="grep_lim.html" TARGET="cont">grep Search Limitations</A>
|
||||
|
||||
<P><A HREF="tl.html" TARGET="cont">Timelines</A>
|
||||
|
||||
<P><A HREF="sequencer.html" TARGET="cont">Event Sequencer</A>
|
||||
|
||||
<P><A HREF="file_category.html" TARGET="cont">File Type Categories</A>
|
||||
|
||||
<P><A HREF="hash_db.html" TARGET="cont">Hash Databases</A>
|
||||
|
||||
<P><A HREF="int_mode.html" TARGET="cont">Image Integrity</A>
|
||||
|
||||
<P><A HREF="timezones.html" TARGET="cont">Time Zones</A>
|
||||
|
||||
</BODY></HTML>
|
@ -1,93 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Metadata Analysis Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>Metadata Analysis</H2></CENTER>
|
||||
<H3>Overview</H3>
|
||||
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.
|
||||
|
||||
<H3>Input</H3>
|
||||
To view the contents of a structure, enter the address in the text
|
||||
box on the left and select <U>Display</U>.
|
||||
|
||||
<P>
|
||||
The <U>Allocation List</U> button can also be used to view the
|
||||
allocation status of metadata structures in groups of 500.
|
||||
|
||||
<H3>Viewing</H3>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The <U>File Type</U> 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.
|
||||
|
||||
<P>
|
||||
If Autopsy has been configured to use hash databases, then one can
|
||||
select which databases to look for the file in. See
|
||||
<A HREF="hash_db.html">Hash Databases</A> for more details.
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The <U>Report</U> option generates an ASCII report with the structure
|
||||
details, MD5 values, and dates in it. The <U>View Contents</U> option
|
||||
displays the allocated data contents as one large file. The <U>Export</U>
|
||||
option allows one to save the data contents to a file. The
|
||||
<U>Add Note</U> button allows one to add a comment about this structure so
|
||||
that it can be later recalled.
|
||||
|
||||
<H3>NTFS Notes</H3>
|
||||
<P>
|
||||
NTFS is a much different design than UNIX file systems and the meta
|
||||
data structures are addressed differently. They typically have
|
||||
the form of <TT>A-B-C</TT>, <TT>88-128-3</TT> for example. The
|
||||
<TT>A</TT> 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 <TT>B</TT> 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, <TT>C</TT>, 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.
|
||||
|
||||
<H3>FAT Notes</H3>
|
||||
<P>
|
||||
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,
|
||||
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
|
||||
<P>
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,49 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Event Sequencer Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>Event Sequencer</H2></CENTER>
|
||||
|
||||
<H3>Overview</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<H3>Adding an Event</H3>
|
||||
<P>
|
||||
To add an event for a file, directory, or meta data structure, select
|
||||
the <U>Add Note</U> 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.
|
||||
|
||||
<P>
|
||||
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
|
||||
<B>Source</B> 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.
|
||||
|
||||
<H3>Viewing the Sequence Events</H3>
|
||||
<P>
|
||||
The <U>Event Sequencer</U> 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.
|
||||
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,68 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Keyword Search Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
|
||||
<CENTER><H2>Keyword Search</H2></CENTER>
|
||||
<H3>Overview</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<H3>Entering the String</H3>
|
||||
|
||||
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.
|
||||
|
||||
<P>
|
||||
If you have not generated a strings file or unallocated data file yet,
|
||||
that option will exist.
|
||||
|
||||
<P>
|
||||
The <U>Load Unallocated Image</U> or <U>Load Allocated Image</U> button
|
||||
exists to switch between the two file types if they have both been
|
||||
generated.
|
||||
|
||||
<P>
|
||||
Autopsy also has the ability to perform pre-configured searches. They
|
||||
are shown in the "Predefined Searches" section.
|
||||
|
||||
<H3>Viewing the Results</H3>
|
||||
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.
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<H3>Previous Searches</H3>
|
||||
The search results are saved to a file so it is easy to recall the
|
||||
results with out having to perform the search again.
|
||||
|
||||
<H3>Regular Expressions</H3>
|
||||
You can use grep regular expressions in the search
|
||||
(refer to the 'grep' <A HREF="grep.html">
|
||||
help page</A> and man page for more details). To search for
|
||||
a couple of different words you would use: <TT>(foo) | (bar)</TT>.
|
||||
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,10 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy File Analysis Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
|
||||
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -1,508 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy File Analysis Help - Time zone</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<p>
|
||||
|
||||
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.
|
||||
|
||||
<p><br>
|
||||
This list was copied from this site:
|
||||
<tt>http://showtunepink.com/ical/TIMEZONES</tt>
|
||||
|
||||
<pre>
|
||||
|
||||
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
|
||||
|
||||
</pre>
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
183
help/tl.html
@ -1,183 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>Autopsy Timeline Analysis Help</TITLE></HEAD>
|
||||
<BODY BGCOLOR=#CCCC99>
|
||||
|
||||
<CENTER><H2>Timeline Mode</H2></CENTER>
|
||||
<H3>Overview</H3>
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
Files have at least three times associated with them. The details of
|
||||
each time varies with the file system type.
|
||||
|
||||
<P>
|
||||
The following times exist for UNIX file systems (EXT2FS & FFS):
|
||||
|
||||
<UL>
|
||||
<LI><B>Modified</B>: 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.
|
||||
|
||||
<LI><B>Accessed</B>: When the file data was last
|
||||
accessed. This time can be modified using the utimes() function.
|
||||
|
||||
<LI><B>Changed</B>: 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).
|
||||
</UL>
|
||||
|
||||
The EXT2FS file system also has a Deleted time, but it is not displayed
|
||||
in the timeline.
|
||||
|
||||
<P>
|
||||
A FAT File system has the following times:
|
||||
<UL>
|
||||
<LI><B>Written</B>: When the file was last written to.
|
||||
It is the ONLY required time in the FAT file system.
|
||||
|
||||
<LI><B>Accessed</B>: 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.
|
||||
|
||||
<LI><B>Created</B>: 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
|
||||
<TT>C:\\Windows</TT> and <TT>C:\\Program Files</TT>.
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
The NTFS File system has several times, four of which are
|
||||
used in the timeline. These times are gathered from the
|
||||
<TT>\$STANDARD_INFORMATION</TT> attribute.
|
||||
<UL>
|
||||
<LI><B>Written</B>: When the file was last written to.
|
||||
|
||||
<LI><B>Accessed</B>: When the file was last accessed.
|
||||
|
||||
<LI><B>Changed</B>: When the MFT entry was last modified.
|
||||
|
||||
<LI><B>Created</B>: When the file was created.
|
||||
</UL>
|
||||
|
||||
|
||||
<H3>How to Create a Timeline</H3>
|
||||
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 <TT>body</TT>
|
||||
file. The second step takes the <TT>body</TT> 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.
|
||||
|
||||
|
||||
<H3>Creating the Body File</H3>
|
||||
The file meta-data must be extracted from the file system images and saved
|
||||
to the <TT>body</TT> file. There are three major types of files that data
|
||||
can be extracted for:
|
||||
<UL>
|
||||
<LI><B>Allocated Files</B>:
|
||||
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.
|
||||
|
||||
<LI><B>Unallocated Files</B>:
|
||||
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.
|
||||
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
To create the <TT>body</TT> 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
|
||||
<TT>output</TT> 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.
|
||||
|
||||
|
||||
<H3>Creating the Timeline</H3>
|
||||
The next window allows one to create a timeline based on the newly
|
||||
created <TT>body</TT> 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.
|
||||
|
||||
<P>
|
||||
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 <TT>/etc/passwd</TT> and
|
||||
<TT>/etc/group</TT> file contents.
|
||||
|
||||
<P>
|
||||
The timeline will be created in the <TT>output</TT> directory.
|
||||
You will be given the option to calculate the MD5 hash value of
|
||||
the new file.
|
||||
|
||||
<H3>Viewing the Timeline</H3>
|
||||
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'.
|
||||
|
||||
<P>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The following columns are in the timeline (in order):
|
||||
<UL>
|
||||
<LI><B>Date and time</B>of the activity. If no date is given,
|
||||
then the activity occured at the same time as the previous entry
|
||||
with a time.
|
||||
|
||||
<LI><B>Size</B>. The size of the file.
|
||||
|
||||
<LI><B>Entry Type</B>. 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.
|
||||
|
||||
<LI><B>Mode</B. The UNIX mode is shown.
|
||||
|
||||
<LI><B>UID</B>. 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.
|
||||
|
||||
<LI><B>GID</B>. 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.
|
||||
|
||||
<LI><B>Meta Data Address</B>. The inode or MFT entry address for the
|
||||
associated file.
|
||||
|
||||
<LI><B>File Name</B>. 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)'.
|
||||
|
||||
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<FONT SIZE=0>Brian Carrier</FONT>
|
||||
</BODY></HTML>
|
@ -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
|
399
lib/Appsort.pm
@ -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
|
||||
"<center><h2>This feature is not available during a live analysis</h2></center>";
|
||||
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 "<frameset cols=\"20%,80%\">\n";
|
||||
|
||||
# Block List
|
||||
print "<frame src=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::MENU&"
|
||||
. "$Args::baseargs\">\n";
|
||||
|
||||
# Blank
|
||||
print "<frame src=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::BLANK&"
|
||||
. "$Args::baseargs\" name=\"content\">\n"
|
||||
. "</frameset>\n";
|
||||
|
||||
Print::print_html_footer_frameset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
# The left-hand frame for running sorter
|
||||
sub menu {
|
||||
Print::print_html_header("sorter menu");
|
||||
|
||||
print "<p><a href=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::ENTER&"
|
||||
. "$Args::baseargs\" "
|
||||
. "target=\"content\">Sort Files by Type</a>";
|
||||
|
||||
print "<p><a href=\"$::PROGNAME?mod=$::MOD_APPSORT&view=$Appsort::VIEW&"
|
||||
. "$Args::baseargs\" "
|
||||
. "target=\"content\">View Sorted Files</a>";
|
||||
|
||||
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 "<center>"
|
||||
. "<h3>File Type Sortings</h3></center><br>"
|
||||
. "<form action=\"$::PROGNAME\" method=\"get\">\n"
|
||||
. "<input type=\"hidden\" name=\"mod\" value=\"$::MOD_APPSORT\">\n"
|
||||
. "<input type=\"hidden\" name=\"view\" value=\"$Appsort::RUN\">\n"
|
||||
. "<input type=\"hidden\" name=\"vol\" value=\"$Args::args{'vol'}\">\n"
|
||||
. Args::make_hidden();
|
||||
|
||||
print <<EOF1;
|
||||
<p>The <b>sorter</b> 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 <tt>$::DATADIR</tt> directory.
|
||||
<hr>
|
||||
EOF1
|
||||
|
||||
my $sort_dir = get_sorter_dir();
|
||||
if (-d "$sort_dir") {
|
||||
print "WARNING: This will overwrite any existing data in:<br>"
|
||||
. " <tt>$sort_dir</tt><br>\n";
|
||||
}
|
||||
|
||||
my $tab = " ";
|
||||
|
||||
print <<EOF2;
|
||||
|
||||
<p>
|
||||
<input type=\"checkbox\" name=\"sorter_cat\" value=\"1\" CHECKED>
|
||||
Sort files into categories by type
|
||||
|
||||
<p>$tab
|
||||
<input type=\"checkbox\" name=\"sorter_unk\" value=\"1\">
|
||||
Do not save data about <tt>unknown</tt> file types
|
||||
|
||||
<p>$tab
|
||||
<input type=\"checkbox\" name=\"sorter_save\" value=\"1\">
|
||||
Save a copy of files in category directory (may require lots of disk space)
|
||||
|
||||
<p>$tab
|
||||
<input type=\"checkbox\" name=\"sorter_img\" value=\"1\">
|
||||
Save ONLY graphic images and make thumbnails <br>
|
||||
$tab (may require lots of disk space and will save to a different directory than sorting all file types)
|
||||
|
||||
<p>
|
||||
<input type=\"checkbox\" name=\"sorter_ext\" value=\"1\" CHECKED>
|
||||
Extension and File Type Validation
|
||||
|
||||
EOF2
|
||||
|
||||
if (($::NSRLDB ne "") && (-e "$::NSRLDB")) {
|
||||
|
||||
# NSRL
|
||||
print
|
||||
"<p><input type=\"checkbox\" name=\"sorter_nsrl\" value=\"1\" CHECKED>"
|
||||
. "Exclude files in the <b>NIST NSRL</b>\n";
|
||||
}
|
||||
|
||||
if (($Caseman::alert_db ne "") && (-e "$Caseman::alert_db")) {
|
||||
print
|
||||
"<p><input type=\"checkbox\" name=\"sorter_alert\" value=\"1\" CHECKED>"
|
||||
. "Alert files that are found in the <b>Alert Hash Database</b>\n";
|
||||
}
|
||||
|
||||
if (($Caseman::exclude_db ne "") && (-e "$Caseman::exclude_db")) {
|
||||
print
|
||||
"<p><input type=\"checkbox\" name=\"sorter_exclude\" value=\"1\" CHECKED>"
|
||||
. "Ignore files that are found in the <b>Exclude Hash Database</b>\n";
|
||||
}
|
||||
|
||||
print "<p><input type=\"image\" src=\"pict/but_ok.jpg\" "
|
||||
. "width=43 height=20 alt=\"Ok\" border=\"0\">\n</form>\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"
|
||||
. "<p><a href=\"$::PROGNAME?mod=$::MOD_APPSORT&"
|
||||
. "view=$Appsort::ENTER&$Args::baseargs\">"
|
||||
. "<img border=0 src=\"pict/but_ok.jpg\" alt=\"Ok\" "
|
||||
. "width=43 height=20></a>\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: <tt>sorter $exec</tt><p>\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 "$_<br>\n";
|
||||
$hit_cnt = 0;
|
||||
}
|
||||
|
||||
close(OUT);
|
||||
|
||||
if (-e "$sort_dir/index.html") {
|
||||
print "<p>Output can be found by viewing:<br>"
|
||||
. " <tt>$sort_dir/index.html</tt><p>\n";
|
||||
|
||||
# Print the index.html file from the output
|
||||
print "<hr><center><h3>Results Summary</h3></center>\n";
|
||||
open INDEX, "<$sort_dir/index.html"
|
||||
or die "Can't open sorter index file ($sort_dir/index.html)";
|
||||
|
||||
while (<INDEX>) {
|
||||
next if ((/^<HTML><HEAD><TITLE>/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;
|
||||
}
|
||||
|
291
lib/Appview.pm
@ -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);
|
||||
}
|
||||
|
927
lib/Args.pm
@ -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;
|
4161
lib/Caseman.pm
927
lib/Data.pm
@ -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;
|
||||
}
|
91
lib/Exec.pm
@ -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;
|
2310
lib/File.pm
@ -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;
|
336
lib/Frame.pm
@ -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;
|
||||
}
|
171
lib/Fs.pm
@ -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;
|
947
lib/Hash.pm
@ -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;
|
||||
}
|
954
lib/Kwsrch.pm
@ -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;
|
357
lib/Main.pm
@ -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;
|
789
lib/Meta.pm
@ -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;
|
||||
}
|
||||
|
1110
lib/Notes.pm
390
lib/Print.pm
@ -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</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" href="global.css">
|
||||
</head>
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
sub print_html_footer_frameset {
|
||||
print "\n</html>\n" . "$::HTTP_NL$::HTTP_NL";
|
||||
}
|
||||
|
||||
# Create the header information with the body tag
|
||||
sub print_html_header {
|
||||
print_html_header_frameset(shift);
|
||||
print "<body bgcolor=\"$::BACK_COLOR\">\n\n";
|
||||
print "<link rel=\"SHORTCUT ICON\" href=\"pict/favicon.ico\">\n";
|
||||
}
|
||||
|
||||
sub print_html_footer {
|
||||
print "\n</body>\n</html>\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 "<body marginheight=0 marginwidth=0 topmargin=0 "
|
||||
. "leftmargin=0 rightmargin=0 botmargin=0 bgcolor=\"$::BACK_COLOR\">\n\n";
|
||||
print "<link rel=\"SHORTCUT ICON\" href=\"pict/favicon.ico\">\n";
|
||||
$is_body = 1;
|
||||
}
|
||||
|
||||
sub print_html_footer_tabs {
|
||||
print "\n</body>\n</html>\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 <<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</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" href="global.css">
|
||||
<script language=\"JavaScript\">
|
||||
<!-- hide script from old browsers
|
||||
document.write(\'<center><font color=\"red\"><p>WARNING: Your browser currently has Java Script enabled.</font><p>You do not need Java Script to use Autopsy and it is recommended that it be turned off for security reasons.<hr></center>\');
|
||||
//-->
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body bgcolor=\"$::BACK_COLOR\">
|
||||
<link rel=\"SHORTCUT ICON\" href=\"pict/favicon.ico\">
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
sub print_html_footer_javascript {
|
||||
print "\n</body>\n</html>\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 <br> 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()) . "<br>\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 <br> and other things that html_encode()
|
||||
# can do. Do not send arbitrary HTML to this function.
|
||||
sub print_err {
|
||||
print html_encode(shift()) . "<br>\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;
|
1425
lib/Timeline.pm
@ -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;
|
@ -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;
|
@ -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;
|
@ -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_DIR>/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 <CASE_DIR>/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_DIR>/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
|
||||
<www.sleuthkit.org/sleuthkit>
|
||||
|
||||
.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 <carrier at sleuthkit dot org>
|
||||
|
||||
Send documentation updates to <doc-updates at sleuthkit dot org>
|
Before Width: | Height: | Size: 305 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB |
BIN
pict/but_ok.jpg
Before Width: | Height: | Size: 881 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 931 B |
Before Width: | Height: | Size: 1.9 KiB |
BIN
pict/favicon.ico
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 941 B |
Before Width: | Height: | Size: 694 B |
Before Width: | Height: | Size: 953 B |
Before Width: | Height: | Size: 725 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 911 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 834 B |
Before Width: | Height: | Size: 1007 B |
Before Width: | Height: | Size: 749 B |
Before Width: | Height: | Size: 923 B |
Before Width: | Height: | Size: 685 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1014 B |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.6 KiB |