diff --git a/DataModel/nbproject/genfiles.properties b/DataModel/nbproject/genfiles.properties index 80fe34e47bb67c19086fab933ca86c6da82deb4b..1051d9cbb36192e81a7d747a80118d88ffe63d35 100644 --- a/DataModel/nbproject/genfiles.properties +++ b/DataModel/nbproject/genfiles.properties @@ -3,6 +3,6 @@ build.xml.script.CRC32=3bd58878 build.xml.stylesheet.CRC32=a56c6a5b@1.42.2 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=d5d42932 +nbproject/build-impl.xml.data.CRC32=68292042 nbproject/build-impl.xml.script.CRC32=b0a13adb -nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.46.1 diff --git a/DataModel/nbproject/project.properties b/DataModel/nbproject/project.properties index 106624d8e802392cd91bcf3279f7f0fd1b120c1d..9c6bd6be1d62077c714df2f6c63df469632728fb 100644 --- a/DataModel/nbproject/project.properties +++ b/DataModel/nbproject/project.properties @@ -1,4 +1,3 @@ -file.reference.sqlite-jdbc-3.6.20.jar=release/modules/ext/sqlite-jdbc-3.6.20.jar file.reference.Tsk_DataModel.jar=release/modules/ext/Tsk_DataModel.jar javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial diff --git a/DataModel/nbproject/project.xml b/DataModel/nbproject/project.xml index 873a58d40b111f97cb16b55431a24b91f2353b25..16adc431b1c6bfb919ea33964109fc22d93a1885 100644 --- a/DataModel/nbproject/project.xml +++ b/DataModel/nbproject/project.xml @@ -59,16 +59,15 @@ <public-packages> <package>org.sleuthkit.autopsy.datamodel</package> <package>org.sleuthkit.datamodel</package> - <package>org.sqlite</package> </public-packages> - <class-path-extension> - <runtime-relative-path>ext/sqlite-jdbc-3.6.20.jar</runtime-relative-path> - <binary-origin>release/modules/ext/sqlite-jdbc-3.6.20.jar</binary-origin> - </class-path-extension> <class-path-extension> <runtime-relative-path>ext/Tsk_DataModel.jar</runtime-relative-path> <binary-origin>release/modules/ext/Tsk_DataModel.jar</binary-origin> </class-path-extension> + <class-path-extension> + <runtime-relative-path>ext/sqlite-jdbc-3.7.2.jar</runtime-relative-path> + <binary-origin>release/modules/ext/sqlite-jdbc-3.7.2.jar</binary-origin> + </class-path-extension> </data> </configuration> </project> diff --git a/DataModel/release/modules/ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar b/DataModel/release/modules/ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar new file mode 100644 index 0000000000000000000000000000000000000000..187bccb2ef290487fa587d8fd55ecd5293a74acd Binary files /dev/null and b/DataModel/release/modules/ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar differ diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/KeyValueThing.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/KeyValueThing.java index 3441bcb9ec492c219c2bb6bccb7a332ef132e9bc..ddf5870bc9fea22787506bb64ab6ad862653f837 100755 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/KeyValueThing.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/KeyValueThing.java @@ -1,22 +1,3 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011 Basis Technology Corp. - * Contact: carrier <at> sleuthkit <dot> org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.sleuthkit.autopsy.datamodel; import java.util.Map; @@ -27,7 +8,7 @@ public class KeyValueThing { String name; /** - * + * * @param map must iterate it keys and values in a consistent order * (use of LinkedHashMap is recommended) * @param id an arbitrary id representing the type of the thing @@ -38,6 +19,12 @@ public KeyValueThing(String name, Map<String, Object> map, int id) { this.id = id; } + public KeyValueThing(String name, int id) { + this.name = name; + this.map = null; + this.id = id; + } + public int getId() { return id; } @@ -49,4 +36,9 @@ public Map<String, Object> getMap() { public String getName() { return name; } + + public void addMap(Map<String,Object> inMap) + { + this.map = inMap; + } } \ No newline at end of file diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/Bundle.properties b/Ingest/src/org/sleuthkit/autopsy/ingest/Bundle.properties index 0e6f76bb3ef1665a5cdd601ef0ba597a3d2931f0..9aef703e9e9b035c48ef68adb969ef194fcc9d55 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/Bundle.properties +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/Bundle.properties @@ -4,7 +4,4 @@ HINT_IngestTopComponent=Ingest window OpenIDE-Module-Name=Ingest IngestTopComponent.topLable.text=Image ingest services IngestTopComponent.startButton.text=Start -IngestTopComponent.messageFrame.title=Ingest Messages IngestTopComponent.refreshFreqLabel.text=Refresh frequency -IngestTopComponent.refreshFrequencyLabel.text=Refresh Frequency -IngestTopComponent.ingestProgressLabel.text=File Ingest Progress diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java index 2f3417721d5b60a4a26411b819868e0ceaa1eff9..249ef5cdc690eb95986ea409a729808a4a6a3cc5 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -39,7 +39,6 @@ import org.netbeans.api.progress.ProgressHandleFactory; import org.openide.util.Cancellable; import org.openide.util.Lookup; -import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType; import org.sleuthkit.datamodel.FsContent; import org.sleuthkit.datamodel.Image; @@ -86,19 +85,25 @@ public class IngestManager { * Notifies services when work is complete or should be interrupted using complete() and stop() calls. * Does not block and can be called multiple times to enqueue more work to already running background process. */ - void execute(final Collection<IngestServiceAbstract> services, final Collection<Image> images) { - - //queuing start - tc.enableStartButton(false); - SwingWorker queueWorker = new EnqueueWorker(services, images); - queueWorker.execute(); + void execute(Collection<IngestServiceAbstract> services, final Collection<Image> images) { + + for (Image image : images) { + for (IngestServiceAbstract service : services) { + switch (service.getType()) { + case Image: + addImage((IngestServiceImage) service, image); + break; + case FsContent: + addFsContent((IngestServiceFsContent) service, image); + break; + default: + logger.log(Level.SEVERE, "Unexpected service type: " + service.getType().name()); + } + } + } logger.log(Level.INFO, "Queues: " + imageQueue.toString() + " " + fsContentQueue.toString()); - - } - - private void startAll() { boolean start = false; if (ingester == null) { start = true; @@ -118,7 +123,6 @@ else if (ingester.isDone() stats = new IngestManagerStats(); ingester.execute(); } - } /** @@ -154,13 +158,6 @@ String getReport() { */ public synchronized void postMessage(final IngestMessage message) { - if (stats != null) { - //record the error for stats, if stats are running - if (message.getMessageType() == MessageType.ERROR) { - stats.addError(message.getSource()); - } - } - SwingUtilities.invokeLater(new Runnable() { @Override @@ -275,27 +272,6 @@ private int getNumImages() { } return ret; } - - private void initMainProgress(final int maximum) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - tc.initProgress(maximum); - } - }); - - - } - - private void updateMainProgress(final int progress) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - tc.updateProgress(progress); - } - }); - - } //manages queue of pending FsContent and IngestServiceFsContent to use on that content //TODO in future content sort will be maintained based on priorities @@ -505,28 +481,6 @@ public String toString() { return sb.toString(); } - public String toHtmlString() { - StringBuilder sb = new StringBuilder(); - sb.append("<html>"); - if (startTime != null) { - sb.append("Start time: ").append(dateFormatter.format(startTime)).append("<br />"); - } - if (endTime != null) { - sb.append("End time: ").append(dateFormatter.format(endTime)).append("<br />"); - } - sb.append("Total ingest time: ").append(getTotalTimeString()).append("<br />"); - sb.append("Total errors: ").append(errorsTotal).append("<br />"); - if (errorsTotal > 0) { - sb.append("Errors per service:"); - for (IngestServiceAbstract service : errors.keySet()) { - final int errorsService = errors.get(service); - sb.append("\t").append(service.getName()).append(": ").append(errorsService).append("<br />"); - } - } - sb.append("</html>"); - return sb.toString(); - } - void start() { startTime = new Date(); } @@ -542,14 +496,6 @@ long getTotalTime() { return endTime.getTime() - startTime.getTime(); } - String getStartTimeString() { - return dateFormatter.format(startTime); - } - - String getEndTimeString() { - return dateFormatter.format(endTime); - } - String getTotalTimeString() { long ms = getTotalTime(); long hours = TimeUnit.MILLISECONDS.toHours(ms); @@ -562,7 +508,7 @@ String getTotalTimeString() { return sb.toString(); } - synchronized void addError(IngestServiceAbstract source) { + void addError(IngestServiceAbstract source) { ++errorsTotal; int curServiceError = errors.get(source); errors.put(source, curServiceError + 1); @@ -606,20 +552,20 @@ public boolean cancel() { try { service.process(unit.content); + //check if new files enqueued + int newImages = getNumImages(); + if (newImages > numImages) { + numImages = newImages + processedImages + 1; + progress.switchToIndeterminate(); + progress.switchToDeterminate(numImages); + + } + progress.progress("Images (" + service.getName() + ")", ++processedImages); + --numImages; } catch (Exception e) { logger.log(Level.INFO, "Exception from service: " + service.getName(), e); stats.addError(service); } - //check if new files enqueued - int newImages = getNumImages(); - if (newImages > numImages) { - numImages = newImages + processedImages + 1; - progress.switchToIndeterminate(); - progress.switchToDeterminate(numImages); - - } - progress.progress("Images (" + service.getName() + ")", ++processedImages); - --numImages; } } @@ -627,8 +573,8 @@ public boolean cancel() { int numFsContents = getNumFsContents(); progress.switchToDeterminate(numFsContents); int processedFiles = 0; - initMainProgress(numFsContents); //process fscontents queue + progress.progress("Running file ingest services."); while (hasNextFsContent()) { QueueUnit<FsContent, IngestServiceFsContent> unit = getNextFsContent(); for (IngestServiceFsContent service : unit.services) { @@ -637,23 +583,21 @@ public boolean cancel() { } try { service.process(unit.content); + int newFsContents = getNumFsContents(); + if (newFsContents > numFsContents) { + //update progress bar if new enqueued + numFsContents = newFsContents + processedFiles + 1; + progress.switchToIndeterminate(); + progress.switchToDeterminate(numFsContents); + + } + progress.progress("Files (" + service.getName() + ")", ++processedFiles); + --numFsContents; } catch (Exception e) { logger.log(Level.INFO, "Exception from service: " + service.getName(), e); stats.addError(service); } } - int newFsContents = getNumFsContents(); - if (newFsContents > numFsContents) { - //update progress bar if new enqueued - numFsContents = newFsContents + processedFiles + 1; - progress.switchToIndeterminate(); - progress.switchToDeterminate(numFsContents); - initMainProgress(numFsContents); - - } - progress.progress("Files", ++processedFiles); - updateMainProgress(processedFiles); - --numFsContents; } logger.log(Level.INFO, "Done background processing"); return null; @@ -691,10 +635,8 @@ protected void done() { stats.end(); progress.finish(); - if (! this.isCancelled()) { - logger.log(Level.INFO, "Summary Report: " + stats.toString()); - tc.displayReport(stats.toHtmlString()); - } + //TODO display report + logger.log(Level.INFO, "STATS: " + stats.toString()); } } @@ -715,100 +657,6 @@ private void handleInterruption() { //empty queues emptyFsContents(); emptyImages(); - - //reset main progress bar - initMainProgress(0); - } - } - - private class EnqueueWorker extends SwingWorker { - - Collection<IngestServiceAbstract> services; - final Collection<Image> images; - int total; - - EnqueueWorker(final Collection<IngestServiceAbstract> services, final Collection<Image> images) { - this.services = services; - this.images = images; - } - private ProgressHandle progress; - - @Override - protected Object doInBackground() throws Exception { - progress = ProgressHandleFactory.createHandle("Queueing Ingest", new Cancellable() { - - @Override - public boolean cancel() { - return EnqueueWorker.this.cancel(true); - } - }); - - total = services.size() * images.size(); - progress.start(total); - //progress.switchToIndeterminate(); - queueAll(services, images); - return null; - } - - @Override - protected void done() { - try { - super.get(); //block and get all exceptions thrown while doInBackground() - } catch (CancellationException e) { - //task was cancelled - handleInterruption(); - - } catch (InterruptedException ex) { - handleInterruption(); - } catch (ExecutionException ex) { - handleInterruption(); - - - } catch (Exception ex) { - handleInterruption(); - - } finally { - //queing end - if (this.isCancelled()) { - //empty queues - emptyFsContents(); - emptyImages(); - } else { - //start ingest workers - startAll(); - } - - progress.finish(); - tc.enableStartButton(true); - } - } - - private void queueAll(Collection<IngestServiceAbstract> services, final Collection<Image> images) { - int processed = 0; - for (Image image : images) { - final String imageName = image.getName(); - for (IngestServiceAbstract service : services) { - final String serviceName = service.getName(); - progress.progress(serviceName + " " + imageName, processed); - switch (service.getType()) { - case Image: - addImage((IngestServiceImage) service, image); - break; - case FsContent: - addFsContent((IngestServiceFsContent) service, image); - break; - default: - logger.log(Level.SEVERE, "Unexpected service type: " + service.getType().name()); - } - progress.progress(serviceName + " " + imageName, ++processed); - } - } - } - - private void handleInterruption() { - //empty queues - emptyFsContents(); - emptyImages(); } } } diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessage.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessage.java index abce9b0fbf64daaba3610063b02579a662fa87cf..23c29277ab4f39720651198e6e4f0d446363f4a3 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessage.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessage.java @@ -18,8 +18,6 @@ */ package org.sleuthkit.autopsy.ingest; -import java.text.SimpleDateFormat; -import java.util.Date; import org.sleuthkit.autopsy.datamodel.KeyValueThing; /** @@ -40,15 +38,12 @@ public enum MessageType { private IngestServiceAbstract source; private String text; private KeyValueThing data; - private Date datePosted; - private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private IngestMessage(long ID, MessageType messageType, IngestServiceAbstract source, String text) { this.ID = ID; this.source = source; this.messageType = messageType; this.text = text; - datePosted = new Date(); } //getters @@ -72,24 +67,17 @@ public MessageType getMessageType() { return messageType; } - public Date getDatePosted() { - return datePosted; - } - @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(Long.toString(ID)).append(": "); sb.append("type: ").append(messageType.name()); - if (source != null) //can be null for manager messages - sb.append(" source: ").append(source.getName()); - sb.append(" date: ").append(dateFormat.format(datePosted)); + sb.append(" source: ").append(source.getName()); sb.append(" text: ").append(text); if (data != null) sb.append(" data: ").append(data.toString()).append(' '); return sb.toString(); } - @Override public boolean equals(Object obj) { @@ -109,23 +97,21 @@ public boolean equals(Object obj) { if (this.source != other.source && (this.source == null || !this.source.equals(other.source))) { return false; } - if (this.datePosted != other.datePosted && (this.datePosted == null || !this.datePosted.equals(other.datePosted))) { - return false; - } return true; } @Override public int hashCode() { int hash = 7; - hash = 29 * hash + (int) (this.ID ^ (this.ID >>> 32)); - hash = 29 * hash + (this.messageType != null ? this.messageType.hashCode() : 0); - hash = 29 * hash + (this.source != null ? this.source.hashCode() : 0); - hash = 29 * hash + (this.text != null ? this.text.hashCode() : 0); - hash = 29 * hash + (this.datePosted != null ? this.datePosted.hashCode() : 0); + hash = 83 * hash + (int) (this.ID ^ (this.ID >>> 32)); + hash = 83 * hash + (this.messageType != null ? this.messageType.hashCode() : 0); + hash = 83 * hash + (this.source != null ? this.source.hashCode() : 0); + hash = 83 * hash + (this.text != null ? this.text.hashCode() : 0); return hash; } + + //factory methods public static IngestMessage createMessage(long ID, MessageType messageType, IngestServiceAbstract source, String message) { @@ -153,9 +139,4 @@ public static IngestMessage createDataMessage(long ID, IngestServiceAbstract sou return im; } - static IngestMessage createManagerMessage(String message) { - IngestMessage im = new IngestMessage(0, MessageType.INFO, null, message); - return im; - } - } diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.form b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.form index f09fc077f32c7ceaff2aa184ecadaa3cae995b7a..c1255b424d34587fe0c49786d7c8e3af4f47ef26 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.form +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.form @@ -16,12 +16,12 @@ <Layout> <DimensionLayout dim="0"> <Group type="103" groupAlignment="0" attributes="0"> - <Component id="mainScrollPane" alignment="0" pref="340" max="32767" attributes="0"/> + <Component id="mainScrollPane" pref="289" max="32767" attributes="0"/> </Group> </DimensionLayout> <DimensionLayout dim="1"> <Group type="103" groupAlignment="0" attributes="0"> - <Component id="mainScrollPane" alignment="0" pref="771" max="32767" attributes="0"/> + <Component id="mainScrollPane" pref="509" max="32767" attributes="0"/> </Group> </DimensionLayout> </Layout> @@ -29,245 +29,129 @@ <Container class="javax.swing.JScrollPane" name="mainScrollPane"> <Properties> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[322, 749]"/> + <Dimension value="[289, 509]"/> </Property> </Properties> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <SubComponents> <Container class="javax.swing.JPanel" name="mainPanel"> - <Properties> - <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[322, 749]"/> - </Property> - </Properties> <Layout> <DimensionLayout dim="0"> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" attributes="0"> - <EmptySpace max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" alignment="1" attributes="0"> - <Component id="controlPanel" max="32767" attributes="1"/> - <EmptySpace min="-2" pref="71" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="topLable" alignment="0" min="-2" max="-2" attributes="1"/> + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> + <Component id="servicesPanel" alignment="0" max="32767" attributes="1"/> + <Component id="freqSlider" alignment="0" max="32767" attributes="1"/> + </Group> + </Group> </Group> <Group type="102" alignment="0" attributes="0"> - <Component id="messageFrame" min="-2" max="-2" attributes="1"/> - <EmptySpace min="-2" pref="48" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="startButton" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="74" max="-2" attributes="0"/> + <Component id="refreshFreqLabel" min="-2" max="-2" attributes="0"/> </Group> </Group> + <EmptySpace pref="173" max="32767" attributes="0"/> </Group> </Group> </DimensionLayout> <DimensionLayout dim="1"> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="24" max="-2" attributes="0"/> + <Component id="topLable" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="servicesPanel" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="startButton" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="18" max="-2" attributes="0"/> + <Component id="freqSlider" min="-2" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/> - <Component id="controlPanel" min="-2" pref="357" max="-2" attributes="0"/> - <EmptySpace min="-2" pref="30" max="-2" attributes="0"/> - <Component id="messageFrame" min="-2" max="-2" attributes="0"/> - <EmptySpace min="-2" pref="127" max="-2" attributes="0"/> + <Component id="refreshFreqLabel" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="198" max="32767" attributes="0"/> </Group> </Group> </DimensionLayout> </Layout> <SubComponents> - <Container class="javax.swing.JInternalFrame" name="messageFrame"> + <Component class="javax.swing.JLabel" name="topLable"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.topLable.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JPanel" name="servicesPanel"> <Properties> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> - <LineBorder roundedCorners="true" thickness="3"> - <Color PropertyName="color" blue="db" green="cd" id="InternalFrame.inactiveTitleBackground" palette="3" red="bf" type="palette"/> - </LineBorder> + <LineBorder/> </Border> </Property> - <Property name="maximizable" type="boolean" value="true"/> - <Property name="resizable" type="boolean" value="true"/> - <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.messageFrame.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> - <Color id="Hand Cursor"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 150]"/> </Property> - <Property name="frameIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> - <Image iconType="0" name="null"/> - </Property> - <Property name="opaque" type="boolean" value="true"/> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[280, 260]"/> + <Dimension value="[200, 150]"/> </Property> - <Property name="visible" type="boolean" value="true"/> </Properties> <Layout> <DimensionLayout dim="0"> <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="274" max="32767" attributes="0"/> - </Group> - </DimensionLayout> - <DimensionLayout dim="1"> - <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="231" max="32767" attributes="0"/> - </Group> - </DimensionLayout> - </Layout> - </Container> - <Container class="javax.swing.JPanel" name="controlPanel"> - - <Layout> - <DimensionLayout dim="0"> - <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" attributes="0"> - <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" attributes="0"> - <EmptySpace max="-2" attributes="0"/> - <Group type="103" groupAlignment="0" attributes="0"> - <Component id="topLable" alignment="0" min="-2" max="-2" attributes="1"/> - <Component id="servicesPanel" alignment="0" min="-2" max="-2" attributes="1"/> - <Component id="startButton" alignment="0" min="-2" max="-2" attributes="0"/> - <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> - <Component id="mainProgressBar" alignment="0" max="32767" attributes="1"/> - <Component id="freqSlider" alignment="0" max="32767" attributes="1"/> - </Group> - </Group> - </Group> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="59" max="-2" attributes="0"/> - <Component id="refreshFrequencyLabel" min="-2" max="-2" attributes="0"/> - </Group> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="59" max="-2" attributes="0"/> - <Component id="ingestProgressLabel" min="-2" max="-2" attributes="0"/> - </Group> - </Group> - <EmptySpace pref="115" max="32767" attributes="0"/> - </Group> - <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="74" max="-2" attributes="0"/> - <Component id="refreshFreqLabel" min="-2" max="-2" attributes="0"/> - <EmptySpace pref="161" max="32767" attributes="0"/> - </Group> - </Group> + <EmptySpace min="0" pref="198" max="32767" attributes="0"/> </Group> </DimensionLayout> <DimensionLayout dim="1"> <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="20" max="-2" attributes="0"/> - <Component id="topLable" min="-2" max="-2" attributes="0"/> - <EmptySpace type="unrelated" max="-2" attributes="0"/> - <Component id="servicesPanel" min="-2" max="-2" attributes="0"/> - <EmptySpace max="-2" attributes="0"/> - <Component id="startButton" min="-2" max="-2" attributes="0"/> - <EmptySpace type="unrelated" max="-2" attributes="0"/> - <Component id="freqSlider" min="-2" max="-2" attributes="0"/> - <EmptySpace max="-2" attributes="0"/> - <Component id="refreshFrequencyLabel" min="-2" pref="14" max="-2" attributes="0"/> - <EmptySpace max="-2" attributes="0"/> - <Component id="mainProgressBar" min="-2" max="-2" attributes="0"/> - <EmptySpace max="-2" attributes="0"/> - <Component id="ingestProgressLabel" min="-2" max="-2" attributes="0"/> - <EmptySpace pref="228" max="32767" attributes="0"/> - </Group> - <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="555" max="-2" attributes="0"/> - <Component id="refreshFreqLabel" min="-2" max="-2" attributes="0"/> - <EmptySpace max="32767" attributes="0"/> - </Group> - </Group> + <EmptySpace min="0" pref="148" max="32767" attributes="0"/> </Group> </DimensionLayout> </Layout> - <SubComponents> - <Component class="javax.swing.JLabel" name="topLable"> - <Properties> - <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> - <Font name="Tahoma" size="12" style="0"/> - </Property> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.topLable.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - </Component> - <Container class="javax.swing.JPanel" name="servicesPanel"> - <Properties> - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> - <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> - <LineBorder/> - </Border> - </Property> - <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[200, 150]"/> - </Property> - <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[200, 150]"/> - </Property> - </Properties> - - <Layout> - <DimensionLayout dim="0"> - <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="198" max="32767" attributes="0"/> - </Group> - </DimensionLayout> - <DimensionLayout dim="1"> - <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="148" max="32767" attributes="0"/> - </Group> - </DimensionLayout> - </Layout> - </Container> - <Component class="javax.swing.JSlider" name="freqSlider"> - <Properties> - <Property name="majorTickSpacing" type="int" value="1"/> - <Property name="maximum" type="int" value="10"/> - <Property name="minimum" type="int" value="1"/> - <Property name="paintLabels" type="boolean" value="true"/> - <Property name="paintTicks" type="boolean" value="true"/> - <Property name="snapToTicks" type="boolean" value="true"/> - </Properties> - <Events> - <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="freqSliderStateChanged"/> - </Events> - </Component> - <Component class="javax.swing.JLabel" name="refreshFreqLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.refreshFreqLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - </Component> - <Component class="javax.swing.JButton" name="startButton"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.startButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Events> - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="startButtonActionPerformed"/> - </Events> - </Component> - <Component class="javax.swing.JLabel" name="refreshFrequencyLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.refreshFrequencyLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - </Component> - <Component class="javax.swing.JProgressBar" name="mainProgressBar"> - </Component> - <Component class="javax.swing.JLabel" name="ingestProgressLabel"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.ingestProgressLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - </Component> - </SubComponents> </Container> + <Component class="javax.swing.JSlider" name="freqSlider"> + <Properties> + <Property name="majorTickSpacing" type="int" value="1"/> + <Property name="maximum" type="int" value="10"/> + <Property name="minimum" type="int" value="1"/> + <Property name="paintLabels" type="boolean" value="true"/> + <Property name="paintTicks" type="boolean" value="true"/> + <Property name="snapToTicks" type="boolean" value="true"/> + </Properties> + <Events> + <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="freqSliderStateChanged"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="startButton"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.startButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="startButtonActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="refreshFreqLabel"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestTopComponent.refreshFreqLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> </SubComponents> </Container> </SubComponents> diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.java index 0711b33bca82991d873bc797f062757507f88365..74b9665604c632a2de5eb00a2c5669ff740e9de5 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestTopComponent.java @@ -21,8 +21,6 @@ import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; import java.beans.PropertyChangeEvent; import java.sql.SQLException; import java.util.ArrayList; @@ -34,7 +32,6 @@ import java.util.logging.Logger; import javax.swing.BoxLayout; import javax.swing.JCheckBox; -import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JSlider; import org.openide.util.NbBundle; @@ -49,22 +46,21 @@ * Top component explorer for the Ingest module. */ public final class IngestTopComponent extends TopComponent implements DataExplorer { - + private static IngestTopComponent instance; private static final Logger logger = Logger.getLogger(IngestTopComponent.class.getName()); private IngestManager manager = null; private Collection<IngestServiceAbstract> services; private Map<String, Boolean> serviceStates; - private IngestMessagePanel messagePanel; private ActionListener serviceSelListener = new ActionListener() { - + @Override public void actionPerformed(ActionEvent ev) { JCheckBox box = (JCheckBox) ev.getSource(); serviceStates.put(box.getName(), box.isSelected()); } }; - + private IngestTopComponent() { services = new ArrayList<IngestServiceAbstract>(); serviceStates = new HashMap<String, Boolean>(); @@ -74,66 +70,41 @@ private IngestTopComponent() { setToolTipText(NbBundle.getMessage(IngestTopComponent.class, "HINT_IngestTopComponent")); //putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE); putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE); - + } - + public static synchronized IngestTopComponent getDefault() { if (instance == null) { instance = new IngestTopComponent(); } return instance; } - + @Override public TopComponent getTopComponent() { return this; } - + @Override public void propertyChange(PropertyChangeEvent evt) { logger.log(Level.INFO, "Unhandled property change: " + evt.getPropertyName()); } - + @Override public int getPersistenceType() { return TopComponent.PERSISTENCE_NEVER; } - + private void customizeComponents() { //custom GUI setup not done by builder freqSlider.setToolTipText("Lower update frequency can optimize performance of certain ingest services, but also reduce real time status feedback"); - + JScrollPane scrollPane = new JScrollPane(servicesPanel); scrollPane.setPreferredSize(this.getSize()); this.add(scrollPane, BorderLayout.CENTER); - + servicesPanel.setLayout(new BoxLayout(servicesPanel, BoxLayout.Y_AXIS)); - - - freqSlider.setEnabled(false); - - messagePanel = new IngestMessagePanel(); - - messagePanel.setOpaque(false); - messageFrame.setOpaque(false); - messageFrame.addComponentListener(new ComponentAdapter() { - - @Override - public void componentResized(ComponentEvent e) { - - super.componentResized(e); - messageFrame.setPreferredSize(messageFrame.getSize()); - } - }); - //make messageframe on top - this.setComponentZOrder(controlPanel, 2); - messageFrame.setContentPane(messagePanel); - messageFrame.pack(); - messageFrame.setVisible(true); - - - Collection<IngestServiceImage> imageServices = IngestManager.enumerateImageServices(); for (IngestServiceImage service : imageServices) { final String serviceName = service.getName(); @@ -144,7 +115,7 @@ public void componentResized(ComponentEvent e) { servicesPanel.add(checkbox); serviceStates.put(serviceName, true); } - + Collection<IngestServiceFsContent> fsServices = IngestManager.enumerateFsContentServices(); for (IngestServiceFsContent service : fsServices) { final String serviceName = service.getName(); @@ -155,7 +126,6 @@ public void componentResized(ComponentEvent e) { servicesPanel.add(checkbox); serviceStates.put(serviceName, true); } - } /** This method is called from within the constructor to @@ -168,41 +138,13 @@ private void initComponents() { mainScrollPane = new javax.swing.JScrollPane(); mainPanel = new javax.swing.JPanel(); - messageFrame = new javax.swing.JInternalFrame(); - controlPanel = new javax.swing.JPanel(); topLable = new javax.swing.JLabel(); servicesPanel = new javax.swing.JPanel(); freqSlider = new javax.swing.JSlider(); - refreshFreqLabel = new javax.swing.JLabel(); startButton = new javax.swing.JButton(); - refreshFrequencyLabel = new javax.swing.JLabel(); - mainProgressBar = new javax.swing.JProgressBar(); - ingestProgressLabel = new javax.swing.JLabel(); - - mainScrollPane.setPreferredSize(new java.awt.Dimension(322, 749)); - - mainPanel.setPreferredSize(new java.awt.Dimension(322, 749)); - - messageFrame.setBorder(new javax.swing.border.LineBorder(javax.swing.UIManager.getDefaults().getColor("InternalFrame.inactiveTitleBackground"), 3, true)); - messageFrame.setMaximizable(true); - messageFrame.setResizable(true); - messageFrame.setTitle(org.openide.util.NbBundle.getMessage(IngestTopComponent.class, "IngestTopComponent.messageFrame.title")); // NOI18N - messageFrame.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - messageFrame.setFrameIcon(null); - messageFrame.setOpaque(true); - messageFrame.setPreferredSize(new java.awt.Dimension(280, 260)); - messageFrame.setVisible(true); - - javax.swing.GroupLayout messageFrameLayout = new javax.swing.GroupLayout(messageFrame.getContentPane()); - messageFrame.getContentPane().setLayout(messageFrameLayout); - messageFrameLayout.setHorizontalGroup( - messageFrameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 274, Short.MAX_VALUE) - ); - messageFrameLayout.setVerticalGroup( - messageFrameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 231, Short.MAX_VALUE) - ); + refreshFreqLabel = new javax.swing.JLabel(); + + mainScrollPane.setPreferredSize(new java.awt.Dimension(289, 509)); topLable.setFont(new java.awt.Font("Tahoma", 0, 12)); org.openide.awt.Mnemonics.setLocalizedText(topLable, org.openide.util.NbBundle.getMessage(IngestTopComponent.class, "IngestTopComponent.topLable.text")); // NOI18N @@ -234,8 +176,6 @@ public void stateChanged(javax.swing.event.ChangeEvent evt) { } }); - org.openide.awt.Mnemonics.setLocalizedText(refreshFreqLabel, org.openide.util.NbBundle.getMessage(IngestTopComponent.class, "IngestTopComponent.refreshFreqLabel.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(startButton, org.openide.util.NbBundle.getMessage(IngestTopComponent.class, "IngestTopComponent.startButton.text")); // NOI18N startButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -243,92 +183,43 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { } }); - org.openide.awt.Mnemonics.setLocalizedText(refreshFrequencyLabel, org.openide.util.NbBundle.getMessage(IngestTopComponent.class, "IngestTopComponent.refreshFrequencyLabel.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(ingestProgressLabel, org.openide.util.NbBundle.getMessage(IngestTopComponent.class, "IngestTopComponent.ingestProgressLabel.text")); // NOI18N - - javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); - controlPanel.setLayout(controlPanelLayout); - controlPanelLayout.setHorizontalGroup( - controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addComponent(topLable) - .addContainerGap(198, Short.MAX_VALUE)) - .addGroup(controlPanelLayout.createSequentialGroup() - .addComponent(servicesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(115, 115, 115)) - .addGroup(controlPanelLayout.createSequentialGroup() - .addComponent(startButton) - .addContainerGap(258, Short.MAX_VALUE)) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(mainProgressBar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(freqSlider, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(115, Short.MAX_VALUE)))) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGap(59, 59, 59) - .addComponent(refreshFrequencyLabel) - .addContainerGap(174, Short.MAX_VALUE)) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGap(59, 59, 59) - .addComponent(ingestProgressLabel) - .addContainerGap(171, Short.MAX_VALUE)) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGap(74, 74, 74) - .addComponent(refreshFreqLabel) - .addContainerGap(161, Short.MAX_VALUE))) - ); - controlPanelLayout.setVerticalGroup( - controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGap(20, 20, 20) - .addComponent(topLable) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(servicesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(startButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(freqSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(refreshFrequencyLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(mainProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(ingestProgressLabel) - .addContainerGap(228, Short.MAX_VALUE)) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGap(555, 555, 555) - .addComponent(refreshFreqLabel) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - ); + org.openide.awt.Mnemonics.setLocalizedText(refreshFreqLabel, org.openide.util.NbBundle.getMessage(IngestTopComponent.class, "IngestTopComponent.refreshFreqLabel.text")); // NOI18N javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel); mainPanel.setLayout(mainPanelLayout); mainPanelLayout.setHorizontalGroup( mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(mainPanelLayout.createSequentialGroup() - .addContainerGap() .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup() - .addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(71, 71, 71)) .addGroup(mainPanelLayout.createSequentialGroup() - .addComponent(messageFrame, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(48, 48, 48)))) + .addContainerGap() + .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(topLable, javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(servicesPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(freqSlider, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGroup(mainPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(startButton)) + .addGroup(mainPanelLayout.createSequentialGroup() + .addGap(74, 74, 74) + .addComponent(refreshFreqLabel))) + .addContainerGap(173, Short.MAX_VALUE)) ); mainPanelLayout.setVerticalGroup( mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(mainPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 357, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(30, 30, 30) - .addComponent(messageFrame, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(127, 127, 127)) + .addGap(24, 24, 24) + .addComponent(topLable) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(servicesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(startButton) + .addGap(18, 18, 18) + .addComponent(freqSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(refreshFreqLabel) + .addContainerGap(198, Short.MAX_VALUE)) ); mainScrollPane.setViewportView(mainPanel); @@ -337,20 +228,19 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 340, Short.MAX_VALUE) + .addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 289, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 771, Short.MAX_VALUE) + .addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE) ); }// </editor-fold>//GEN-END:initComponents private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed - if (manager == null) { + if (manager == null) return; - } - + //pick the services List<IngestServiceAbstract> servicesToStart = new ArrayList<IngestServiceAbstract>(); for (IngestServiceAbstract service : services) { @@ -373,7 +263,7 @@ private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F images.add(image); } catch (TskException e) { logger.log(Level.SEVERE, "Error ingesting image, can't retrieve image id: " + Integer.toString(imageId), e); - + } catch (SQLException e) { logger.log(Level.SEVERE, "Error ingesting image, can't retrieve image id: " + Integer.toString(imageId), e); } @@ -381,25 +271,20 @@ private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F manager.execute(servicesToStart, images); }//GEN-LAST:event_startButtonActionPerformed - + private void freqSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_freqSliderStateChanged JSlider source = (JSlider) evt.getSource(); if (!source.getValueIsAdjusting()) { final int refresh = (int) source.getValue(); manager.setUpdateFrequency(refresh); - + } }//GEN-LAST:event_freqSliderStateChanged // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JPanel controlPanel; private javax.swing.JSlider freqSlider; - private javax.swing.JLabel ingestProgressLabel; private javax.swing.JPanel mainPanel; - private javax.swing.JProgressBar mainProgressBar; private javax.swing.JScrollPane mainScrollPane; - private javax.swing.JInternalFrame messageFrame; private javax.swing.JLabel refreshFreqLabel; - private javax.swing.JLabel refreshFrequencyLabel; private javax.swing.JPanel servicesPanel; private javax.swing.JButton startButton; private javax.swing.JLabel topLable; @@ -410,51 +295,37 @@ public void componentOpened() { logger.log(Level.INFO, "IngestTopComponent opened()"); manager = new IngestManager(this); } - + @Override public void componentClosed() { logger.log(Level.INFO, "IngestTopComponent closed()"); } - - void enableStartButton(boolean enable) { - startButton.setEnabled(enable); - } - + void writeProperties(java.util.Properties p) { // better to version settings since initial version as advocated at // http://wiki.apidesign.org/wiki/PropertyFiles p.setProperty("version", "1.0"); - + } - + void readProperties(java.util.Properties p) { String version = p.getProperty("version"); - + } /** * Display ingest summary report in some dialog */ void displayReport(String ingestReport) { - JOptionPane.showMessageDialog( - null, - ingestReport, - "Ingest Summary", - JOptionPane.INFORMATION_MESSAGE); + //TODO widget + logger.log(Level.INFO, "INGEST REPORT: " + ingestReport); } /** * Display IngestMessage from service (forwarded by IngestManager) */ void displayMessage(IngestMessage ingestMessage) { - messagePanel.addMessage(ingestMessage); - } - - void initProgress(int maximum) { - this.mainProgressBar.setMaximum(maximum); - } - - void updateProgress(int progress) { - this.mainProgressBar.setValue(progress); + //TODO widget + logger.log(Level.INFO, "INGEST MESSAGE: " + ingestMessage.toString()); } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java index a152a75f068c778109ba7cb15b88970e2ec0dd0f..2497254bf1183ba2ab2b7c69c29c2cea24aa881f 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java @@ -69,7 +69,7 @@ public void init(IngestManager manager) { logger.log(Level.INFO, "init()"); this.manager = manager; - manager.postMessage(IngestMessage.createMessage(1, MessageType.WARNING, this, "INIT")); + manager.postMessage(IngestMessage.createMessage(1, MessageType.INFO, this, "INIT")); } @Override diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java index 7e85fbf0d980b20aebac3e6b8297763eaf2307e3..a3637b82ff7644f8595d8445d35cd69379f3ba32 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java @@ -44,7 +44,6 @@ import org.apache.solr.client.solrj.response.TermsResponse; import org.apache.commons.httpclient.NoHttpResponseException; import org.apache.solr.client.solrj.SolrRequest; -import org.apache.solr.client.solrj.SolrRequest.METHOD; import org.openide.modules.InstalledFileLocator; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; diff --git a/RecentActivity/build.xml b/RecentActivity/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..5c34a68973c58ec52d1bc46197b60f8fe1ad093a --- /dev/null +++ b/RecentActivity/build.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- You may freely edit this file. See harness/README in the NetBeans platform --> +<!-- for some information on what you could do (e.g. targets to override). --> +<!-- If you delete this file and reopen the project it will be recreated. --> +<project name="org.sleuthkit.autopsy.recentactivity" default="netbeans" basedir="."> + <description>Builds, tests, and runs the project org.sleuthkit.autopsy.recentactivity.</description> + <import file="nbproject/build-impl.xml"/> +</project> diff --git a/RecentActivity/manifest.mf b/RecentActivity/manifest.mf new file mode 100644 index 0000000000000000000000000000000000000000..b8bdf7aa3bb150ee20b510b7d514d1134f43750e --- /dev/null +++ b/RecentActivity/manifest.mf @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.sleuthkit.autopsy.recentactivity +OpenIDE-Module-Layer: org/sleuthkit/autopsy/recentactivity/layer.xml +OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/recentactivity/Bundle.properties +OpenIDE-Module-Requires: + org.openide.modules.InstalledFileLocator, + org.openide.windows.TopComponent$Registry, + org.openide.windows.WindowManager +OpenIDE-Module-Specification-Version: 1.0 + diff --git a/RecentActivity/nbproject/build-impl.xml b/RecentActivity/nbproject/build-impl.xml new file mode 100644 index 0000000000000000000000000000000000000000..276cc6a4d14342e7d9166f134484cec2378daf90 --- /dev/null +++ b/RecentActivity/nbproject/build-impl.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +*** GENERATED FROM project.xml - DO NOT EDIT *** +*** EDIT ../build.xml INSTEAD *** +--> +<project name="org.sleuthkit.autopsy.recentactivity-impl" basedir=".."> + <fail message="Please build using Ant 1.7.1 or higher."> + <condition> + <not> + <antversion atleast="1.7.1"/> + </not> + </condition> + </fail> + <property file="nbproject/private/suite-private.properties"/> + <property file="nbproject/suite.properties"/> + <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail> + <property file="${suite.dir}/nbproject/private/platform-private.properties"/> + <property file="${suite.dir}/nbproject/platform.properties"/> + <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2"> + <attribute name="name"/> + <attribute name="value"/> + <sequential> + <property name="@{name}" value="${@{value}}"/> + </sequential> + </macrodef> + <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2"> + <attribute name="property"/> + <attribute name="value"/> + <sequential> + <property name="@{property}" value="@{value}"/> + </sequential> + </macrodef> + <property file="${user.properties.file}"/> + <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> + <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> + <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> + <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness)."> + <condition> + <not> + <contains string="${cluster.path.evaluated}" substring="platform"/> + </not> + </condition> + </fail> + <import file="${harness.dir}/build.xml"/> +</project> diff --git a/RecentActivity/nbproject/genfiles.properties b/RecentActivity/nbproject/genfiles.properties new file mode 100644 index 0000000000000000000000000000000000000000..fca57470c60c753c45a3231e7ae3c8cb23cdaae4 --- /dev/null +++ b/RecentActivity/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=c008ddb2 +build.xml.script.CRC32=d323407a +build.xml.stylesheet.CRC32=a56c6a5b@1.46.1 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=c008ddb2 +nbproject/build-impl.xml.script.CRC32=aef16a21 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.46.1 diff --git a/RecentActivity/nbproject/platform.properties b/RecentActivity/nbproject/platform.properties new file mode 100644 index 0000000000000000000000000000000000000000..38ecd5a92ebea2c14710d0595bdd2d6df0bafcf4 --- /dev/null +++ b/RecentActivity/nbproject/platform.properties @@ -0,0 +1,99 @@ +cluster.path=\ + ${nbplatform.active.dir}/java:\ + ${nbplatform.active.dir}/platform +disabled.modules=\ + org.apache.tools.ant.module,\ + org.netbeans.api.debugger.jpda,\ + org.netbeans.api.java,\ + org.netbeans.libs.cglib,\ + org.netbeans.libs.javacapi,\ + org.netbeans.libs.javacimpl,\ + org.netbeans.libs.jsr223,\ + org.netbeans.libs.springframework,\ + org.netbeans.modules.ant.browsetask,\ + org.netbeans.modules.ant.debugger,\ + org.netbeans.modules.ant.freeform,\ + org.netbeans.modules.ant.grammar,\ + org.netbeans.modules.ant.kit,\ + org.netbeans.modules.beans,\ + org.netbeans.modules.classfile,\ + org.netbeans.modules.dbschema,\ + org.netbeans.modules.debugger.jpda,\ + org.netbeans.modules.debugger.jpda.ant,\ + org.netbeans.modules.debugger.jpda.projects,\ + org.netbeans.modules.debugger.jpda.ui,\ + org.netbeans.modules.form,\ + org.netbeans.modules.form.j2ee,\ + org.netbeans.modules.form.kit,\ + org.netbeans.modules.hibernate,\ + org.netbeans.modules.hibernatelib,\ + org.netbeans.modules.hudson.ant,\ + org.netbeans.modules.hudson.maven,\ + org.netbeans.modules.i18n,\ + org.netbeans.modules.i18n.form,\ + org.netbeans.modules.j2ee.core.utilities,\ + org.netbeans.modules.j2ee.eclipselink,\ + org.netbeans.modules.j2ee.eclipselinkmodelgen,\ + org.netbeans.modules.j2ee.jpa.refactoring,\ + org.netbeans.modules.j2ee.jpa.verification,\ + org.netbeans.modules.j2ee.metadata,\ + org.netbeans.modules.j2ee.metadata.model.support,\ + org.netbeans.modules.j2ee.persistence,\ + org.netbeans.modules.j2ee.persistence.kit,\ + org.netbeans.modules.j2ee.persistenceapi,\ + org.netbeans.modules.j2ee.toplinklib,\ + org.netbeans.modules.java.api.common,\ + org.netbeans.modules.java.debug,\ + org.netbeans.modules.java.editor,\ + org.netbeans.modules.java.editor.lib,\ + org.netbeans.modules.java.examples,\ + org.netbeans.modules.java.freeform,\ + org.netbeans.modules.java.guards,\ + org.netbeans.modules.java.helpset,\ + org.netbeans.modules.java.hints,\ + org.netbeans.modules.java.hints.processor,\ + org.netbeans.modules.java.j2seplatform,\ + org.netbeans.modules.java.j2seproject,\ + org.netbeans.modules.java.kit,\ + org.netbeans.modules.java.lexer,\ + org.netbeans.modules.java.navigation,\ + org.netbeans.modules.java.platform,\ + org.netbeans.modules.java.preprocessorbridge,\ + org.netbeans.modules.java.project,\ + org.netbeans.modules.java.source,\ + org.netbeans.modules.java.source.ant,\ + org.netbeans.modules.java.sourceui,\ + org.netbeans.modules.javadoc,\ + org.netbeans.modules.javawebstart,\ + org.netbeans.modules.jellytools,\ + org.netbeans.modules.jellytools.java,\ + org.netbeans.modules.junit,\ + org.netbeans.modules.maven,\ + org.netbeans.modules.maven.coverage,\ + org.netbeans.modules.maven.embedder,\ + org.netbeans.modules.maven.grammar,\ + org.netbeans.modules.maven.graph,\ + org.netbeans.modules.maven.hints,\ + org.netbeans.modules.maven.indexer,\ + org.netbeans.modules.maven.junit,\ + org.netbeans.modules.maven.kit,\ + org.netbeans.modules.maven.model,\ + org.netbeans.modules.maven.osgi,\ + org.netbeans.modules.maven.persistence,\ + org.netbeans.modules.maven.repository,\ + org.netbeans.modules.maven.search,\ + org.netbeans.modules.maven.spring,\ + org.netbeans.modules.projectimport.eclipse.core,\ + org.netbeans.modules.projectimport.eclipse.j2se,\ + org.netbeans.modules.refactoring.java,\ + org.netbeans.modules.spellchecker.bindings.java,\ + org.netbeans.modules.spring.beans,\ + org.netbeans.modules.swingapp,\ + org.netbeans.modules.websvc.jaxws21,\ + org.netbeans.modules.websvc.jaxws21api,\ + org.netbeans.modules.websvc.saas.codegen.java,\ + org.netbeans.modules.xml.jaxb,\ + org.netbeans.modules.xml.tools.java,\ + org.openide.compat,\ + org.openide.util.enumerations +nbplatform.active=default diff --git a/RecentActivity/nbproject/project.properties b/RecentActivity/nbproject/project.properties new file mode 100644 index 0000000000000000000000000000000000000000..0feca1f89d641f9877fa49bbb35cbe3428e4a66f --- /dev/null +++ b/RecentActivity/nbproject/project.properties @@ -0,0 +1,3 @@ +file.reference.jcalendarbutton-1.4.5.jar=release/modules/ext/jcalendarbutton-1.4.5.jar +javac.source=1.6 +javac.compilerargs=-Xlint -Xlint:-serial diff --git a/RecentActivity/nbproject/project.xml b/RecentActivity/nbproject/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..cfff641740ef56a4bcb6d76376e2b83c8227a44f --- /dev/null +++ b/RecentActivity/nbproject/project.xml @@ -0,0 +1,193 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://www.netbeans.org/ns/project/1"> + <type>org.netbeans.modules.apisupport.project</type> + <configuration> + <data xmlns="http://www.netbeans.org/ns/nb-module-project/3"> + <code-name-base>org.sleuthkit.autopsy.recentactivity</code-name-base> + <suite-component/> + <module-dependencies> + <dependency> + <code-name-base>org.netbeans.modules.options.api</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.22.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.netbeans.modules.settings</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.31.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.awt</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>7.31.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.dialogs</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>7.20.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.explorer</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>6.35.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.modules</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>7.23.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.nodes</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>7.21.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.util</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>8.15.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.util.lookup</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>8.8.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.openide.windows</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>6.40.1</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.casemodule</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.corecomponentinterfaces</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.corecomponents</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.coreutils</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>0-1</release-version> + <specification-version>0.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.datamodel</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.directorytree</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.filesearch</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>1</release-version> + <specification-version>1.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.ingest</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>0-1</release-version> + <specification-version>1.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>0-1</release-version> + <specification-version>0.0</specification-version> + </run-dependency> + </dependency> + <dependency> + <code-name-base>org.sleuthkit.autopsy.menuactions</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <release-version>0-1</release-version> + <specification-version>0.0</specification-version> + </run-dependency> + </dependency> + </module-dependencies> + <public-packages/> + <class-path-extension> + <runtime-relative-path>ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar</runtime-relative-path> + <binary-origin>release/modules/ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar</binary-origin> + </class-path-extension> + <class-path-extension> + <runtime-relative-path>ext/jcalendarbutton-1.4.5.jar</runtime-relative-path> + <binary-origin>release/modules/ext/jcalendarbutton-1.4.5.jar</binary-origin> + </class-path-extension> + </data> + </configuration> +</project> diff --git a/RecentActivity/nbproject/suite.properties b/RecentActivity/nbproject/suite.properties new file mode 100644 index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92 --- /dev/null +++ b/RecentActivity/nbproject/suite.properties @@ -0,0 +1 @@ +suite.dir=${basedir}/.. diff --git a/RecentActivity/release/modules/ext/jcalendarbutton-1.4.5.jar b/RecentActivity/release/modules/ext/jcalendarbutton-1.4.5.jar new file mode 100644 index 0000000000000000000000000000000000000000..4128ca1e05a3e57d1b1a98cf56643daca8e102f2 Binary files /dev/null and b/RecentActivity/release/modules/ext/jcalendarbutton-1.4.5.jar differ diff --git a/RecentActivity/release/modules/ext/sqlite-jdbc-3.6.20.jar b/RecentActivity/release/modules/ext/sqlite-jdbc-3.6.20.jar new file mode 100644 index 0000000000000000000000000000000000000000..2009143653bdc88b5ebbbeb4f588eead97c3784c Binary files /dev/null and b/RecentActivity/release/modules/ext/sqlite-jdbc-3.6.20.jar differ diff --git a/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.2.jar b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..b0bec7b000d369a8f3dcaa9c6cd0b3ce87aed454 Binary files /dev/null and b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.2.jar differ diff --git a/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar new file mode 100644 index 0000000000000000000000000000000000000000..187bccb2ef290487fa587d8fd55ecd5293a74acd Binary files /dev/null and b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.6.3-20110609.081603-3.jar differ diff --git a/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.7.1-20110713.014305-1.jar b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.7.1-20110713.014305-1.jar new file mode 100644 index 0000000000000000000000000000000000000000..4dbeb15cf4306ac9f949847e71b68f65946f02e3 Binary files /dev/null and b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.7.1-20110713.014305-1.jar differ diff --git a/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.8-20111025.014814-1.jar b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.8-20111025.014814-1.jar new file mode 100644 index 0000000000000000000000000000000000000000..bcea83745ab32246e315dd0c53209dc6a0cd39b9 Binary files /dev/null and b/RecentActivity/release/modules/ext/sqlite-jdbc-3.7.8-20111025.014814-1.jar differ diff --git a/RecentActivity/release/modules/ext/sqlite4java.jar b/RecentActivity/release/modules/ext/sqlite4java.jar new file mode 100644 index 0000000000000000000000000000000000000000..6622f51c65f70592b7ffbb9debeb21c4c23f637d Binary files /dev/null and b/RecentActivity/release/modules/ext/sqlite4java.jar differ diff --git a/RecentActivity/release/modules/ext/sqlitejdbc-v056.jar b/RecentActivity/release/modules/ext/sqlitejdbc-v056.jar new file mode 100644 index 0000000000000000000000000000000000000000..f95d90eb07094f8646118332f50cb2cd4597d80f Binary files /dev/null and b/RecentActivity/release/modules/ext/sqlitejdbc-v056.jar differ diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivity.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..ce72e7ef54d69df02daa2c70cfe9cbb4dea3fc74 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivity.java @@ -0,0 +1,46 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author arivera + */ +public enum BrowserActivity { + IE(0), + FF(1), + CH(2); + private static final Map<Integer,BrowserActivity> lookup + = new HashMap<Integer,BrowserActivity>(); + + static { + for(BrowserActivity bat : values()) + lookup.put(bat.type, bat); + } + + + private int type; + + private BrowserActivity(int type) + { + this.type = type; + } + + public int getType() { return type; } + + public static BrowserActivity get(int type) { + switch(type) { + case 0: return IE; + case 1: return FF; + case 2: return CH; + } + return null; + } + +} \ No newline at end of file diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivityModel.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivityModel.java new file mode 100644 index 0000000000000000000000000000000000000000..247bd1b25ce3a4101f8e9dfb0588ebc5deb4bc0f --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivityModel.java @@ -0,0 +1,28 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.util.ArrayList; +import java.util.Map; + +/** + * + * @author Alex + */ +public class BrowserActivityModel { + + int count = 0; + private ArrayList<Map<BrowserActivity,Map>> BAM = new ArrayList<Map<BrowserActivity,Map>>(); + public BrowserActivityModel(){ + init(); + } + + public void init() + { + + } + +} + diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivityType.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivityType.java new file mode 100644 index 0000000000000000000000000000000000000000..b22a80975f59acf97041974c4e6af84a3c8ed8a6 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserActivityType.java @@ -0,0 +1,46 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author arivera + */ +public enum BrowserActivityType { + Cookies(0), + Url(1), + Bookmarks(2); + private static final Map<Integer,BrowserActivityType> lookup + = new HashMap<Integer,BrowserActivityType>(); + + static { + for(BrowserActivityType bat : values()) + lookup.put(bat.type, bat); + } + + + private int type; + + private BrowserActivityType(int type) + { + this.type = type; + } + + public int getType() { return type; } + + public static BrowserActivityType get(int type) { + switch(type) { + case 0: return Cookies; + case 1: return Url; + case 2: return Bookmarks; + } + return null; + } + +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserModel.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserModel.java new file mode 100644 index 0000000000000000000000000000000000000000..ca887a7872bda0251592cb507d3fffd567a81e1e --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserModel.java @@ -0,0 +1,47 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.util.ArrayList; +import javax.swing.AbstractListModel; +import javax.swing.ListModel; + +/** + * + * @author Alex + */ +public abstract class BrowserModel extends AbstractListModel implements ListModel { + + private int id; + private int visit_count; + private String last_accessed; + private String from_visit; + private String url; + private String title; + private String type; + private String browser; + + public BrowserModel(){ + + } + + public BrowserModel(int ID, String browser, int count, String accessed, String reference, String path, String name) { + this.id = ID; + this.type = type; + this.browser = browser; + this.visit_count = count; + this.last_accessed = accessed; + this.from_visit = reference; + this.url = path; + this.title = name; + + } + + public ArrayList<BrowserModel> getresults() + { + return null; + } + +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserType.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserType.java new file mode 100644 index 0000000000000000000000000000000000000000..494a10ba1088b2951c3e7936b2e915d41af30b42 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/BrowserType.java @@ -0,0 +1,45 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author arivera + */ +public enum BrowserType { + IE(0), //Internet Explorer + FF(1), //Firefox + CH(2); //Chrome + private static final Map<Integer,BrowserType> lookup + = new HashMap<Integer,BrowserType>(); + + static { + for(BrowserType bt : values()) + lookup.put(bt.type, bt); + } + + + private int type; + + private BrowserType(int type) + { + this.type = type; + } + + public int getType() { return type; } + + public static BrowserType get(int type) { + switch(type) { + case 0: return IE; + case 1: return FF; + case 2: return CH; + } + return null; + } + +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties new file mode 100644 index 0000000000000000000000000000000000000000..fc21672edd5c40e82e657d6e46dc2d9d8dc19e50 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties @@ -0,0 +1,24 @@ +OpenIDE-Module-Name=RecentActivity +RecentActivityTopComponent.makeNodesButton.text=Get Recent Activity +RecentActivityTopComponent.jLabel1.text=Filter Options +RecentActivityTopComponent.jLabel2.text=Browser Activity +RecentActivityTopComponent.jLabel3.text=jLabel3 +RecentActivityTopComponent.jLabel4.text=Registry Information +RecentActivityTopComponent.jLabel5.text=Date/Time +RecentActivityTopComponent.jLabel6.text=Recent Activity Keyword Filter +RecentActivityTopComponent.jTextField1.text= +RecentActivityTopComponent.jLabel5.toolTipText= +RecentActivityTopComponent.jLabel6.toolTipText= +RecentActivityTopComponent.jLabel7.text=to +RecentActivityTopComponent.dateFromTextField.text= +RecentActivityTopComponent.dateToTextField.text= +RecentActivityTopComponent.dateToButtonCalendar.text= +RecentActivityTopComponent.dateFromButtonCalendar.text= +RecentActivityTopComponent.jTextField1.toolTipText=Enter a word or words you'd like to pattern match against +RecentActivityTopComponent.jCheckBox1.AccessibleContext.accessibleName=IEhistory +RecentActivityTopComponent.jCheckBox1.label= +RecentActivityTopComponent.IEhistory.text= +RecentActivityTopComponent.FFhistory.text=jCheckBox3 +RecentActivityTopComponent.CHhistory.text=jCheckBox2 +RecentActivityTopComponent.Cookies.text=jCheckBox4 +RecentActivityTopComponent.Bookmarks.text=jCheckBox5 diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java new file mode 100644 index 0000000000000000000000000000000000000000..6cf37cc2953e15ebc9dd8d1c17dd98929523792c --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java @@ -0,0 +1,207 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.autopsy.datamodel.ContentUtils; +import java.sql.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.lang.*; +import java.util.*; +import java.io.File; +import java.io.IOException; +/** + * + * @author Alex + */ + + +public class Chrome { + + + public static final String chquery = "SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, " + + "urls.last_visit_time, urls.hidden, visits.visit_time, visits.from_visit, visits.transition FROM urls, visits WHERE urls.id = visits.url"; + public static final String chcookiequery = "select name, value, host, expires_utc, last_access_utc, creation_utc from cookies"; + public static final String chbookmarkquery = "SELECT starred.title, urls.url, starred.date_added, starred.date_modified, urls.typed_count, urls._last_visit_time FROM starred INNER JOIN urls ON urls.id = starred.url_id"; + public List<Map> als = new ArrayList(); + public ArrayList<HashMap> cookies = new ArrayList<HashMap>(); + public ArrayList<HashMap> bookmarks = new ArrayList<HashMap>(); + private final Logger logger = Logger.getLogger(this.getClass().getName()); + + public Chrome(){ + + } + + public void getchdb(){ + + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List<FsContent> FFSqlitedb; + Map<String, Object> kvs = new LinkedHashMap<String, Object>(); + + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'History' AND parent_path LIKE '%Chrome%'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(chquery); + + + + while(temprs.next()) + { + kvs.clear(); + kvs.put("Url", temprs.getString("url")); + kvs.put("Title", ((temprs.getString("title") != null) ? temprs.getString("title") : "No Title")); + kvs.put("Count", temprs.getString("visit_count")); + kvs.put("Last Accessed", temprs.getString("visit_date")); + kvs.put("Reference", temprs.getString("from_visit")); + als.add(kvs); + + } + tempdbconnect.closeConnection(); + temprs.close(); + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + + j++; + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Firefox SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } + + //COOKIES section + // This gets the cookie info + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List<FsContent> FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'Cookies' and parent_path LIKE '%Chrome%'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + File dbFile = new File(temps); + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(chcookiequery); + while(temprs.next()) + { + HashMap<String, Object> kvs = new HashMap<String, Object>(); + kvs.put("Url", temprs.getString("host")); + kvs.put("Title", ((temprs.getString("name") != null) ? temprs.getString("name") : "No name")); + kvs.put("Count", temprs.getString("value")); + kvs.put("Last Accessed", temprs.getString("access_utc")); + kvs.put("Reference", temprs.getString("creation_utc")); + cookies.add(kvs); + + } + tempdbconnect.closeConnection(); + temprs.close(); + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + j++; + dbFile.delete(); + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Firefox SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } + + //COOKIES section + // This gets the cookie info + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List<FsContent> FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'Bookmarks' and parent_path LIKE '%Chrome%'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + File dbFile = new File(temps); + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(chbookmarkquery); + while(temprs.next()) + { + HashMap<String, Object> kvs = new HashMap<String, Object>(); + kvs.put("Url", temprs.getString("urls.url")); + kvs.put("Title", ((temprs.getString("starred.title") != null) ? temprs.getString("starred.title") : "No name")); + kvs.put("Count", temprs.getString("urls.typed_count")); + kvs.put("Last Accessed", temprs.getString("urls._last_visit_time")); + kvs.put("Reference", temprs.getString("starred.date_added")); + bookmarks.add(kvs); + + } + tempdbconnect.closeConnection(); + temprs.close(); + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + j++; + dbFile.delete(); + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Firefox SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } + + } +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java new file mode 100644 index 0000000000000000000000000000000000000000..e1f97ba74cfda7317e78d3753fb048c5f06c815f --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java @@ -0,0 +1,213 @@ +package org.sleuthkit.autopsy.recentactivity; + +//IO imports +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +// SQL imports +import java.sql.ResultSet; + +//Util Imports +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +// TSK Imports +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.datamodel.ContentUtils; +import org.sleuthkit.autopsy.datamodel.KeyValueThing; +import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.SleuthkitCase; + + +public class ExtractIE { // implements BrowserActivity { + + //Constants region + private final String indexDatQueryStr = "select * from tsk_files where name LIKE '%index.dat%'"; + + private final String PASCO_HOME = System.getenv("PASCO_HOME"); + private final String PASCO_RESULTS_PATH = PASCO_HOME + "\\results"; + private final String PASCO_LIB_PATH = PASCO_HOME + "\\pasco2.jar;" + + PASCO_HOME + "\\lib\\*"; + + //Results List to be referenced/used outside the class + public ArrayList<HashMap<String,Object>> PASCO_RESULTS_LIST = new ArrayList<HashMap<String,Object>>(); + //Look Up Table that holds Pasco2 results + private HashMap<String, Object> PASCO_RESULTS_LUT ; + + private KeyValueThing IE_PASCO_LUT = new KeyValueThing(BrowserType.IE.name(), BrowserType.IE.getType()); + + public LinkedHashMap<String, Object> IE_OBJ; + + //Get this case + private Case currentCase = Case.getCurrentCase(); + private SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + + //Singleton logger object. + private final Logger logger = Logger.getLogger(this.getClass().getName()); + + public ExtractIE(){ + init(); + } + + //@Override + public KeyValueThing getRecentActivity() + { + return IE_PASCO_LUT; + } + + void init() + { + try + { + Collection<FsContent> FsContentCollection; + ResultSet rs = tempDb.runQuery(indexDatQueryStr); + FsContentCollection = tempDb.resultSetToFsContents(rs); + + String temps; + String indexFileName; + int index = 0; + + for(FsContent fsc : FsContentCollection) + { + // Since each result represent an index.dat file, + // just create these files with the following notation: + // index<Number>.dat (i.e. index0.dat, index1.dat,..., indexN.dat) + // Write each index.dat file to a temp directory. + indexFileName = "index" + Integer.toString(index) + ".dat"; + temps = currentCase.getTempDirectory() + "\\" + indexFileName; + File datFile = new File(temps); + ContentUtils.writeToFile(fsc, datFile); + boolean bPascProcSuccess = executePasco(temps, index); + + //At this point pasco2 proccessed the index files. + //Now fetch the results, parse them and the delete the files. + if(bPascProcSuccess) + { + //Delete index<n>.dat file since it was succcessfully by Pasco + datFile.delete(); + } + ++index; + } + } + catch(Exception ioex) + { + logger.log(Level.SEVERE, "Error while trying to write index.dat files.", ioex); + } + } + + + //Simple wrapper to JavaSystemCaller.Exec() to execute pasco2 jar + // TODO: Hardcoded command args/path needs to be removed. Maybe set some constants and set env variables for classpath + // I'm not happy with this code. Can't stand making a system call, is not an acceptable solution but is a hack for now. + private boolean executePasco(String indexFilePath, int fileIndex) + { + boolean success = true; + + try + { + List<String> command = new ArrayList<String>(); + + command.add("-cp"); + command.add(PASCO_LIB_PATH); + command.add(" isi.pasco2.Main"); + command.add(" -T history"); + command.add(indexFilePath); + command.add(" > " + PASCO_RESULTS_PATH + "\\pasco2Result" + Integer.toString(fileIndex) + ".txt"); + + String[] cmd = command.toArray(new String[0]); + + JavaSystemCaller.Exec.execute("java", cmd); + + } + catch(Exception e) + { + success = false; + logger.log(Level.SEVERE, "ExtractIE::executePasco() -> " ,e.getMessage() ); + } + + return success; + } + + public void parsePascoResults() + { + // First thing we want to do is check to make sure the results directory + // is not empty. + File rFile = new File(PASCO_RESULTS_PATH); + + //Let's make sure our list and lut are empty. + //PASCO_RESULTS_LIST.clear(); + + if(rFile.exists()) + { + //Give me a list of pasco results in that directory + File[] pascoFiles = rFile.listFiles(); + + if(pascoFiles.length > 0) + { + try + { + for (File file : pascoFiles) + { + + // Make sure the file the is not empty or the Scanner will + // throw a "No Line found" Exception + if (file != null && file.length() > 0 ) + { + Scanner fileScanner = new Scanner(new FileInputStream(file.toString())); + //Skip the first three lines + fileScanner.nextLine(); + fileScanner.nextLine(); + fileScanner.nextLine(); + + while (fileScanner.hasNext()) + { + String line = fileScanner.nextLine(); + //Need to change this pattern a bit because there might + //be instances were "V" might not apply. + String pattern = "(?)URL(\\s)(V|\\:)"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(line); + if(m.find()) + { + String[] lineBuff = line.split("\\t"); + PASCO_RESULTS_LUT = new HashMap<String,Object>(); + PASCO_RESULTS_LUT.put(BrowserActivityType.Url.name(), lineBuff[1]); + PASCO_RESULTS_LUT.put("Title", lineBuff[2]); + PASCO_RESULTS_LUT.put("Count", lineBuff[0]); + PASCO_RESULTS_LUT.put("Last Accessed", lineBuff[3]); + + PASCO_RESULTS_LUT.put("Reference", "None"); + //KeyValueThing + //This will be redundant in terms IE.name() because of + //the way they implemented KeyValueThing + IE_OBJ = new LinkedHashMap<String,Object>(); + IE_OBJ.put(BrowserType.IE.name(), PASCO_RESULTS_LUT); + IE_PASCO_LUT.addMap(IE_OBJ); + + PASCO_RESULTS_LIST.add(PASCO_RESULTS_LUT); + } + } + } + //TODO: Fix Delete issue + boolean bDelete = file.delete(); + } + } + catch(IOException ioex) + { + logger.log(Level.SEVERE, "ExtractIE::parsePascosResults() -> " ,ioex.getMessage() ); + } + + } + } + } + +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..b2e81c3eb0e4a18ac97df4a4e55464bbf7d3d165 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -0,0 +1,128 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import com.sun.corba.se.spi.activation.Server; +import java.io.File; +import java.io.IOException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.openide.modules.InstalledFileLocator; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.datamodel.ContentUtils; +import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.SleuthkitCase; + +/** + * + * @author Alex \System32\Config + */ +public class ExtractRegistry { + + public Logger logger = Logger.getLogger(this.getClass().getName()); + + ExtractRegistry(){ + } + + + +public void getregistryfiles(){ + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List<FsContent> Regfiles; + ResultSet rs = tempDb.runQuery("select * from tsk_files where lower(name) = 'ntuser.dat' OR lower(parent_path) LIKE '%/system32/config%' and (name = 'system' OR name = 'software' OR name = 'SECURITY' OR name = 'SAM' OR name = 'default')"); + Regfiles = tempDb.resultSetToFsContents(rs); + + int j = 0; + + while (j < Regfiles.size()) + { + + String temps = currentCase.getTempDirectory() + "\\" + Regfiles.get(j).getName().toString(); + ContentUtils.writeToFile(Regfiles.get(j), new File(currentCase.getTempDirectory() + "\\" + Regfiles.get(j).getName())); + File regFile = new File(temps); + + boolean regSuccess = executeRegRip(temps, j); + + //At this point pasco2 proccessed the index files. + //Now fetch the results, parse them and the delete the files. + if(regSuccess) + { + //Delete index<n>.dat file since it was succcessfully by Pasco + regFile.delete(); + } + j++; + + + + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Registry files", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } +} + +//Simple wrapper to JavaSystemCaller.Exec() to execute pasco2 jar + // TODO: Hardcoded command args/path needs to be removed. Maybe set some constants and set env variables for classpath + // I'm not happy with this code. Can't stand making a system call, is not an acceptable solution but is a hack for now. + private boolean executeRegRip(String regFilePath, int fileIndex) + { + boolean success = true; + String type = ""; + File rrFolder = InstalledFileLocator.getDefault().locate("rr", Server.class.getPackage().getName(), false); + // String instanceDir = rrFolder.getAbsolutePath() + File.separator + "rr"; + + try + { + if(regFilePath.toLowerCase().contains("system")) + { + type = "system"; + } + if(regFilePath.toLowerCase().contains("software")) + { + type = "software"; + } + if(regFilePath.toLowerCase().contains("ntuser")) + { + type = "ntuser"; + } + if(regFilePath.toLowerCase().contains("default")) + { + type = "default"; + } + if(regFilePath.toLowerCase().contains("sam")) + { + type = "sam"; + } + if(regFilePath.toLowerCase().contains("security")) + { + type = "security"; + } + String command = "rip -r " + regFilePath +" -f " + type + " >> " + regFilePath + type + Integer.toString(fileIndex) + ".txt"; + + JavaSystemCaller.Exec.execute(command); + + } + catch(Exception e) + { + success = false; + logger.log(Level.SEVERE, "ExtractRegistry::executeRegRip() -> " ,e.getMessage() ); + } + + return success; + } + + +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java new file mode 100644 index 0000000000000000000000000000000000000000..e7bbdc33e4d65d71c1c77d32533f5700d1c06df6 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java @@ -0,0 +1,177 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.autopsy.datamodel.ContentUtils; +import java.sql.*; +import java.util.logging.Level; +import java.util.logging.Logger; +//<editor-fold defaultstate="collapsed" desc="comment"> +import java.lang.*; +//</editor-fold> +import java.util.*; +import java.io.File; +import java.io.IOException; +/** + * + * @author Alex + */ +public class Firefox { + + private static final String ffquery = "SELECT moz_historyvisits.id,url,title,visit_count,visit_date,from_visit FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id AND hidden = 0"; + private static final String ffcookiequery = "SELECT name,value,host,expiry,lastAccessed,creationTime FROM moz_cookies"; + private static final String ffbookmarkquery = "SELECT fk, moz_bookmarks.title, url FROM moz_bookmarks INNER JOIN moz_places ON moz_bookmarks.fk=moz_places.id"; + + public ArrayList<HashMap> als = new ArrayList<HashMap>(); + public Logger logger = Logger.getLogger(this.getClass().getName()); + public ArrayList<HashMap> cookies = new ArrayList<HashMap>(); + public ArrayList<HashMap> bookmarks = new ArrayList<HashMap>(); + public Firefox(){ + + } + + public void getffdb(){ + //Make these seperate, this is for history + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List<FsContent> FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE '%places.sqlite%' and parent_path LIKE '%Firefox%'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + File dbFile = new File(temps); + + + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(ffquery); + while(temprs.next()) + { + + HashMap<String, Object> kvs = new HashMap<String, Object>(); + kvs.put("Url", temprs.getString("url")); + kvs.put("Title", ((temprs.getString("title") != null) ? temprs.getString("title") : "No Title")); + kvs.put("Count", temprs.getString("visit_count")); + kvs.put("Last Accessed", temprs.getString("visit_date")); + kvs.put("Reference", temprs.getString("from_visit")); + als.add(kvs); + + } + temprs.close(); + ResultSet tempbm = tempdbconnect.executeQry(ffbookmarkquery); + while(tempbm.next()) + { + + HashMap<String, Object> kvs = new HashMap<String, Object>(); + kvs.put("Url", temprs.getString("url")); + kvs.put("Title", ((temprs.getString("title") != null) ? temprs.getString("title") : "No Title")); + kvs.put("Count", ""); + kvs.put("Last Accessed", ""); + kvs.put("Reference", ""); + bookmarks.add(kvs); + + } + tempbm.close(); + tempdbconnect.closeConnection(); + + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + j++; + dbFile.delete(); + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Firefox SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } + + + //COOKIES section + // This gets the cookie info + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List<FsContent> FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE '%cookies.sqlite%' and parent_path LIKE '%Firefox%'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + File dbFile = new File(temps); + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(ffcookiequery); + while(temprs.next()) + { + + HashMap<String, Object> kvs = new HashMap<String, Object>(); + kvs.put("Url", temprs.getString("host")); + kvs.put("Title", ((temprs.getString("name") != null) ? temprs.getString("name") : "No name")); + kvs.put("Count", temprs.getString("value")); + kvs.put("Last Accessed", temprs.getString("lastAccessed")); + kvs.put("Reference", temprs.getString("creationTime")); + cookies.add(kvs); + + } + tempdbconnect.closeConnection(); + temprs.close(); + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + j++; + dbFile.delete(); + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Firefox SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } + } +} + //@Override +// public HashMap<String,String> ExtractActivity() { +// return ExtractActivity; +// +// } + + + + + + + diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/JavaSystemCaller.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/JavaSystemCaller.java new file mode 100644 index 0000000000000000000000000000000000000000..3fc7947130b592330e427d87069e094c9a9e4202 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/JavaSystemCaller.java @@ -0,0 +1,342 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; + +/** + * Make a system call through a system shell in a platform-independent manner in Java. <br /> + * This class only demonstrate a 'dir' or 'ls' within current (execution) path, if no parameters are used. + * If parameters are used, the first one is the system command to execute, the others are its system command parameters. <br /> + * To be system independent, an <b><a href="http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm"> + * Abstract Factory Pattern</a></b> will be used to build the right underlying system shell in which the system command will be executed. + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + * @see <a href="http://stackoverflow.com/questions/236737#236873"> + How to make a system call that returns the stdout output as a string in various languages?</a> + */ +public final class JavaSystemCaller +{ + + /** + * Execute a system command. <br /> + * Default is 'ls' in current directory if no parameters, or a system command (if Windows, it is automatically translated to 'dir') + * @param args first element is the system command, the others are its parameters (NOT NULL) + * @throws IllegalArgumentException if one parameters is null or empty. + * 'args' can be empty (default 'ls' performed then) + */ + public static void main(final String[] args) + { + String anOutput = ""; + if(args.length == 0) + { + anOutput = Exec.execute("ls"); + } + else + { + String[] someParameters = null; + anOutput = Exec.execute(args[0],someParameters); + } + System.out.println("Final output: " + anOutput); + } + /** + * Asynchronously read the output of a given input stream. <br /> + * Any exception during execution of the command in managed in this thread. + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public static class StreamGobbler extends Thread + { + private InputStream is; + private String type; + private StringBuffer output = new StringBuffer(); + + StreamGobbler(final InputStream anIs, final String aType) + { + this.is = anIs; + this.type = aType; + } + + /** + * Asynchronous read of the input stream. <br /> + * Will report output as its its displayed. + * @see java.lang.Thread#run() + */ + @Override + public final void run() + { + try + { + final InputStreamReader isr = new InputStreamReader(this.is); + final BufferedReader br = new BufferedReader(isr); + String line=null; + while ( (line = br.readLine()) != null) + { + System.out.println(this.type + ">" + line); + this.output.append(line+System.getProperty("line.separator")); + } + } catch (final IOException ioe) + { + ioe.printStackTrace(); + } + } + /** + * Get output filled asynchronously. <br /> + * Should be called after execution + * @return final output + */ + public final String getOutput() + { + return this.output.toString(); + } + } + /** + * Execute a system command in the appropriate shell. <br /> + * Read asynchronously stdout and stderr to report any result. + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public static final class Exec + { + + /** + * Execute a system command. <br /> + * Listen asynchronously to stdout and stderr + * @param aCommand system command to be executed (must not be null or empty) + * @param someParameters parameters of the command (must not be null or empty) + * @return final output (stdout only) + */ + public static String execute(final String aCommand, final String... someParameters) + { + String output = ""; + try + { + ExecEnvironmentFactory anExecEnvFactory = getExecEnvironmentFactory(aCommand, someParameters); + final IShell aShell = anExecEnvFactory.createShell(); + final String aCommandLine = anExecEnvFactory.createCommandLine(); + + final Runtime rt = Runtime.getRuntime(); + System.out.println("Executing " + aShell.getShellCommand() + " " + aCommandLine); + + final Process proc = rt.exec(aShell.getShellCommand() + " " + aCommandLine); + // any error message? + final StreamGobbler errorGobbler = new + StreamGobbler(proc.getErrorStream(), "ERROR"); + + // any output? + final StreamGobbler outputGobbler = new + StreamGobbler(proc.getInputStream(), "OUTPUT"); + + // kick them off + errorGobbler.start(); + outputGobbler.start(); + + // any error??? + final int exitVal = proc.waitFor(); + System.out.println("ExitValue: " + exitVal); + + output = outputGobbler.getOutput(); + + } catch (final Throwable t) + { + t.printStackTrace(); + } + return output; + } + + private static ExecEnvironmentFactory getExecEnvironmentFactory(final String aCommand, final String... someParameters) + { + final String anOSName = System.getProperty("os.name" ); + if(anOSName.toLowerCase().startsWith("windows")) + { + return new WindowsExecEnvFactory(aCommand, someParameters); + } + return new UnixExecEnvFactory(aCommand, someParameters); + // TODO be more specific for other OS. + } + + private Exec() { /**/ } + } + private JavaSystemCaller() { /**/ } + + /* + * ABSTRACT FACTORY PATTERN + */ + /** + * Environment needed to be build for the Exec class to be able to execute the system command. <br /> + * Must have the right shell and the right command line. <br /> + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public abstract static class ExecEnvironmentFactory + { + private String command = null; + private ArrayList<String> parameters = new ArrayList<String>(); + final String getCommand() { return this.command; } + final ArrayList<String> getParameters() { return this.parameters; } + /** + * Builds an execution environment for a system command to be played. <br /> + * Independent from the OS. + * @param aCommand system command to be executed (must not be null or empty) + * @param someParameters parameters of the command (must not be null or empty) + */ + public ExecEnvironmentFactory(final String aCommand, final String... someParameters) + { + if(aCommand == null || aCommand.length() == 0) { throw new IllegalArgumentException("Command must not be empty"); } + this.command = aCommand; + for (int i = 0; i < someParameters.length; i++) { + final String aParameter = someParameters[i]; + if(aParameter == null || aParameter.length() == 0) { throw new IllegalArgumentException("Parameter n° '"+i+"' must not be empty"); } + this.parameters.add(aParameter); + } + } + /** + * Builds the right Shell for the current OS. <br /> + * Allow for independent platform execution. + * @return right shell, NEVER NULL + */ + public abstract IShell createShell(); + /** + * Builds the right command line for the current OS. <br /> + * Means that a command might be translated, if it does not fit the right OS ('dir' => 'ls' on unix) + * @return right complete command line, with parameters added (NEVER NULL) + */ + public abstract String createCommandLine(); + + protected final String buildCommandLine(final String aCommand, final ArrayList<String> someParameters) + { + final StringBuilder aCommandLine = new StringBuilder(); + aCommandLine.append(aCommand); + for (String aParameter : someParameters) { + aCommandLine.append(" "); + aCommandLine.append(aParameter); + } + return aCommandLine.toString(); + } + } + + /** + * Builds a Execution Environment for Windows. <br /> + * Cmd with windows commands + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public static final class WindowsExecEnvFactory extends ExecEnvironmentFactory + { + + /** + * Builds an execution environment for a Windows system command to be played. <br /> + * Any command not from windows will be translated in its windows equivalent if possible. + * @param aCommand system command to be executed (must not be null or empty) + * @param someParameters parameters of the command (must not be null or empty) + */ + public WindowsExecEnvFactory(final String aCommand, final String... someParameters) + { + super(aCommand, someParameters); + } + /** + * @see test.JavaSystemCaller.ExecEnvironmentFactory#createShell() + */ + @Override + public IShell createShell() { + return new WindowsShell(); + } + + /** + * @see test.JavaSystemCaller.ExecEnvironmentFactory#createCommandLine() + */ + @Override + public String createCommandLine() { + String aCommand = getCommand(); + if(aCommand.toLowerCase().trim().equals("ls")) { aCommand = "dir"; } + // TODO translates other Unix commands + return buildCommandLine(aCommand, getParameters()); + } + } + + /** + * Builds a Execution Environment for Unix. <br /> + * Sh with Unix commands + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public static final class UnixExecEnvFactory extends ExecEnvironmentFactory + { + + /** + * Builds an execution environment for a Unix system command to be played. <br /> + * Any command not from Unix will be translated in its Unix equivalent if possible. + * @param aCommand system command to be executed (must not be null or empty) + * @param someParameters parameters of the command (must not be null or empty) + */ + public UnixExecEnvFactory(final String aCommand, final String... someParameters) + { + super(aCommand, someParameters); + } + /** + * @see test.JavaSystemCaller.ExecEnvironmentFactory#createShell() + */ + @Override + public IShell createShell() { + return new UnixShell(); + } + + /** + * @see test.JavaSystemCaller.ExecEnvironmentFactory#createCommandLine() + */ + @Override + public String createCommandLine() { + String aCommand = getCommand(); + if(aCommand.toLowerCase().trim().equals("dir")) { aCommand = "ls"; } + // TODO translates other Windows commands + return buildCommandLine(aCommand, getParameters()); + } + } + + /** + * System Shell with its right OS command. <br /> + * 'cmd' for Windows or 'sh' for Unix, ... + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public interface IShell + { + /** + * Get the right shell command. <br /> + * Used to launch a new shell + * @return command used to launch a Shell (NEVEL NULL) + */ + String getShellCommand(); + } + /** + * Windows shell (cmd). <br /> + * More accurately 'cmd /C' + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public static class WindowsShell implements IShell + { + /** + * @see test.JavaSystemCaller.IShell#getShellCommand() + */ + @Override + public final String getShellCommand() { + final String osName = System.getProperty("os.name" ); + if( osName.equals( "Windows 95" ) ) { return "command.com /C"; } + return "cmd.exe /C"; + } + } + /** + * Unix shell (sh). <br /> + * More accurately 'sh -C' + * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> + */ + public static class UnixShell implements IShell + { + /** + * @see test.JavaSystemCaller.IShell#getShellCommand() + */ + @Override + public final String getShellCommand() { + return "/bin/sh -c"; + } + } +} \ No newline at end of file diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityDataExplorer.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityDataExplorer.java new file mode 100644 index 0000000000000000000000000000000000000000..61691364d8eaddc8cb979877b445cfb388d92515 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityDataExplorer.java @@ -0,0 +1,119 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.beans.PropertyChangeEvent; +import java.lang.reflect.Array; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.lookup.ServiceProvider; +import org.openide.windows.TopComponent; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer; +import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; +import org.sleuthkit.autopsy.datamodel.KeyValueThing; +import java.util.Random.*; +import java.util.*; +import java.util.logging.Logger; + + +@ServiceProvider(service = DataExplorer.class) +public class RecentActivityDataExplorer implements DataExplorer { + + RecentActivityTopComponent tc; + + static final int NUMBER_THING_ID = 41234; + private final Logger logger = Logger.getLogger(this.getClass().getName()); + private Collection<KeyValueThing> things = new ArrayList<KeyValueThing>(); + + //Empty Constructor + public RecentActivityDataExplorer() { + tc = new RecentActivityTopComponent(this); + tc.setName("Recent Activity"); + tc.edx.tc.setbrowsercheckboxes(0,0,0,0,0); + } + + @Override + public org.openide.windows.TopComponent getTopComponent() { + return tc; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + // nothing to do in simple example + } + + + + public void getallactivity() + { + Firefox ffre = new Firefox(); + ffre.getffdb(); + Chrome chre = new Chrome(); + chre.getchdb(); + } + +void makeNodes() + { + things.clear(); + ExtractRegistry eree = new ExtractRegistry(); + eree.getregistryfiles(); + Firefox ffre = new Firefox(); + ffre.getffdb(); + Chrome chre = new Chrome(); + chre.getchdb(); + ExtractIE eere = new ExtractIE(); + eere.parsePascoResults(); + + + + ArrayList<HashMap<String,Object>> IEresults = eere.PASCO_RESULTS_LIST; + int cookiescount = 0; + int bookmarkscount = 0; + int iecount = IEresults.size(); + bookmarkscount = ffre.bookmarks.size() + chre.bookmarks.size(); + cookiescount = ffre.cookies.size() + chre.cookies.size(); + int ffcount = ffre.als.size(); + int chcount = chre.als.size(); + ExtractRegistry regob = new ExtractRegistry(); + regob.getregistryfiles(); + + + for(Map<String,Object> FFmap : ffre.als){ + things.add(new KeyValueThing("FireFox", FFmap, NUMBER_THING_ID)); + } + + for(HashMap<String,Object> IEmap : IEresults){ + things.add(new KeyValueThing("Internet Explorer", IEmap, NUMBER_THING_ID)); + } + for(Map<String,Object> CHmap : chre.als){ + things.add(new KeyValueThing("Chrome", CHmap, NUMBER_THING_ID)); + } + + for(Map<String,Object> FFCookies : ffre.cookies){ + things.add(new KeyValueThing("Cookie", FFCookies, NUMBER_THING_ID)); + } + for(Map<String,Object> FFBookmark : ffre.bookmarks){ + things.add(new KeyValueThing("Bookmark", FFBookmark, NUMBER_THING_ID)); + } + + for(Map<String,Object> CHCookies : chre.cookies){ + things.add(new KeyValueThing("Cookie", CHCookies, NUMBER_THING_ID)); + } + + for(Map<String,Object> CHBookmark : chre.bookmarks){ + things.add(new KeyValueThing("Bookmark", CHBookmark, NUMBER_THING_ID)); + } + + Children childThingNodes = Children.create(new RecentActivityKeyValueChildFactory(things), true); + tc.setbrowsercheckboxes(iecount,ffcount,chcount,cookiescount,bookmarkscount); + Node rootNode = new AbstractNode(childThingNodes); + String pathText = "Recent User Activity"; + TopComponent searchResultWin = DataResultTopComponent.createInstance("Recent Activity", pathText, rootNode, things.size()); + + searchResultWin.requestActive(); // make it the active top component + + } +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityKeyValueChildFactory.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityKeyValueChildFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..48e9a3c3466f0616af2ec4f6f7836bbf8698e6ac --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityKeyValueChildFactory.java @@ -0,0 +1,28 @@ +package org.sleuthkit.autopsy.recentactivity; + +import java.util.Collection; +import java.util.List; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.datamodel.KeyValueNode; +import org.sleuthkit.autopsy.datamodel.KeyValueThing; + +public class RecentActivityKeyValueChildFactory extends ChildFactory<KeyValueThing> { + + private Collection<KeyValueThing> things; + + public RecentActivityKeyValueChildFactory(Collection<KeyValueThing> things) { + this.things = things; + } + + @Override + protected boolean createKeys(List<KeyValueThing> toPopulate) { + return toPopulate.addAll(things); + } + + @Override + protected Node createNodeForKey(KeyValueThing thing) { + return new KeyValueNode(thing, Children.LEAF); + } +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityModel.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityModel.java new file mode 100644 index 0000000000000000000000000000000000000000..60224828d1073b142ac271d2022a0e3fe3178a22 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityModel.java @@ -0,0 +1,26 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; +import java.util.ArrayList; +import javax.swing.AbstractListModel; +import javax.swing.ListModel; + + +public class RecentActivityModel { + + private String name; + private ArrayList<BrowserModel> data; + + public RecentActivityModel (){ + + } + + public RecentActivityModel(String name, ArrayList<BrowserModel> data) { + this.name = name; + this.data = data; + } + +} + diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityTopComponent.form b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityTopComponent.form new file mode 100644 index 0000000000000000000000000000000000000000..abe16fa0d9eb1c5fc387eca73bcdadf29574a2db --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityTopComponent.form @@ -0,0 +1,327 @@ +<?xml version="1.1" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="makeNodesButton" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="activityProgressBar" min="-2" pref="190" max="-2" attributes="0"/> + </Group> + <Component id="jLabel1" alignment="0" min="-2" pref="84" max="-2" attributes="0"/> + <Component id="jSeparator1" alignment="1" pref="414" max="32767" attributes="0"/> + <Component id="jLabel6" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jTextField1" alignment="0" min="-2" pref="146" max="-2" attributes="0"/> + <Component id="Bookmarks" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="CHhistory" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="Cookies" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="IEhistory" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="FFhistory" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="0" min="-2" pref="179" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="dateFromTextField" min="-2" pref="92" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="0" max="-2" attributes="0"/> + <Component id="dateFromButtonCalendar" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="6" max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="dateToTextField" min="-2" pref="92" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="0" max="-2" attributes="0"/> + <Component id="dateToButtonCalendar" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="activityProgressBar" max="32767" attributes="1"/> + <Component id="makeNodesButton" alignment="0" max="32767" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" pref="14" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jSeparator1" min="-2" pref="7" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTextField1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="IEhistory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="FFhistory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="CHhistory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="Cookies" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="Bookmarks" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="97" max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="dateFromTextField" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="0" groupAlignment="1" attributes="0"> + <Group type="103" alignment="1" groupAlignment="3" attributes="0"> + <Component id="dateToTextField" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="dateToButtonCalendar" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="1" max="-2" attributes="0"/> + </Group> + <Component id="dateFromButtonCalendar" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="102" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="makeNodesButton"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.makeNodesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="makeNodesButtonActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="11" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JSeparator" name="jSeparator1"> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="11" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane2"> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JList" name="jList2"> + <Properties> + <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor"> + <StringArray count="5"> + <StringItem index="0" value="Item 1"/> + <StringItem index="1" value="Item 2"/> + <StringItem index="2" value="Item 3"/> + <StringItem index="3" value="Item 4"/> + <StringItem index="4" value="Item 5"/> + </StringArray> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JCheckBox" name="IEhistory"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.IEhistory.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jCheckBox1.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </AccessibilityProperties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="IEhistoryActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JCheckBox" name="CHhistory"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.CHhistory.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="FFhistory"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.FFhistory.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="Cookies"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.Cookies.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="Bookmarks"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.Bookmarks.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="11" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel5.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel5.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="11" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel6.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel6.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextField1"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jTextField1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jTextField1.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.jLabel7.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JFormattedTextField" name="dateFromTextField"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.dateFromTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="dateFromTextFieldFocusLost"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFormattedTextField(this.dateFormat);"/> + </AuxValues> + </Component> + <Component class="org.sourceforge.jcalendarbutton.JCalendarButton" name="dateFromButtonCalendar"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.dateFromButtonCalendar.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="dateFromPopupChanged"/> + </Events> + </Component> + <Component class="org.sourceforge.jcalendarbutton.JCalendarButton" name="dateToButtonCalendar"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.dateToButtonCalendar.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="dateToPopupChanged"/> + </Events> + </Component> + <Component class="javax.swing.JFormattedTextField" name="dateToTextField"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="org/sleuthkit/autopsy/recentactivity/Bundle.properties" key="RecentActivityTopComponent.dateToTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="dateToTextFieldFocusLost"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFormattedTextField(this.dateFormat);"/> + </AuxValues> + </Component> + <Component class="javax.swing.JProgressBar" name="activityProgressBar"> + <AuxValues> + <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JProgressBar(0, 100)"/> + </AuxValues> + </Component> + </SubComponents> +</Form> diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityTopComponent.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityTopComponent.java new file mode 100644 index 0000000000000000000000000000000000000000..ea644c93db9154b24ae082c4e1f36659b64d893f --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentActivityTopComponent.java @@ -0,0 +1,364 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * RecentActivityTopComponent.java + * + * Created on Dec 12, 2011, 1:55:46 PM + */ +package org.sleuthkit.autopsy.recentactivity; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import org.openide.windows.TopComponent; +import javax.swing.JFormattedTextField; +/** + * + * @author pmartel + */ +public class RecentActivityTopComponent extends TopComponent { + + RecentActivityDataExplorer edx; + DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); + + /** Creates new form RecentActivityTopComponent */ + public RecentActivityTopComponent(RecentActivityDataExplorer edx) { + this.edx = edx; + initComponents(); + } + + JFormattedTextField getDateFromTextField() { + return dateFromTextField; + } + + JFormattedTextField getDateToTextField() { + return dateToTextField; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + makeNodesButton = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jSeparator1 = new javax.swing.JSeparator(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jScrollPane2 = new javax.swing.JScrollPane(); + jList2 = new javax.swing.JList(); + IEhistory = new javax.swing.JCheckBox(); + CHhistory = new javax.swing.JCheckBox(); + FFhistory = new javax.swing.JCheckBox(); + Cookies = new javax.swing.JCheckBox(); + Bookmarks = new javax.swing.JCheckBox(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jTextField1 = new javax.swing.JTextField(); + jLabel7 = new javax.swing.JLabel(); + dateFromTextField = new JFormattedTextField(this.dateFormat); + dateFromButtonCalendar = new org.sourceforge.jcalendarbutton.JCalendarButton(); + dateToButtonCalendar = new org.sourceforge.jcalendarbutton.JCalendarButton(); + dateToTextField = new JFormattedTextField(this.dateFormat); + activityProgressBar = new javax.swing.JProgressBar(0, 100); + + makeNodesButton.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.makeNodesButton.text")); // NOI18N + makeNodesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + makeNodesButtonActionPerformed(evt); + } + }); + + jLabel1.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel1.text")); // NOI18N + + jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel2.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel2.text")); // NOI18N + + jLabel3.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel3.text")); // NOI18N + + jLabel4.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel4.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel4.text")); // NOI18N + + jList2.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public Object getElementAt(int i) { return strings[i]; } + }); + jScrollPane2.setViewportView(jList2); + + IEhistory.setSelected(true); + IEhistory.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.IEhistory.text")); // NOI18N + IEhistory.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + IEhistoryActionPerformed(evt); + } + }); + + CHhistory.setSelected(true); + CHhistory.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.CHhistory.text")); // NOI18N + + FFhistory.setSelected(true); + FFhistory.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.FFhistory.text")); // NOI18N + + Cookies.setSelected(true); + Cookies.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.Cookies.text")); // NOI18N + + Bookmarks.setSelected(true); + Bookmarks.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.Bookmarks.text")); // NOI18N + + jLabel5.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel5.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel5.text")); // NOI18N + jLabel5.setToolTipText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel5.toolTipText")); // NOI18N + + jLabel6.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel6.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel6.text")); // NOI18N + jLabel6.setToolTipText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel6.toolTipText")); // NOI18N + + jTextField1.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jTextField1.text")); // NOI18N + jTextField1.setToolTipText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jTextField1.toolTipText")); // NOI18N + + jLabel7.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jLabel7.text")); // NOI18N + + dateFromTextField.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.dateFromTextField.text")); // NOI18N + dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + dateFromTextFieldFocusLost(evt); + } + }); + + dateFromButtonCalendar.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.dateFromButtonCalendar.text")); // NOI18N + dateFromButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + public void propertyChange(java.beans.PropertyChangeEvent evt) { + dateFromPopupChanged(evt); + } + }); + + dateToButtonCalendar.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.dateToButtonCalendar.text")); // NOI18N + dateToButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + public void propertyChange(java.beans.PropertyChangeEvent evt) { + dateToPopupChanged(evt); + } + }); + + dateToTextField.setText(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.dateToTextField.text")); // NOI18N + dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + dateToTextFieldFocusLost(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(makeNodesButton) + .addGap(18, 18, 18) + .addComponent(activityProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 414, Short.MAX_VALUE) + .addComponent(jLabel6) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 146, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(Bookmarks) + .addGroup(layout.createSequentialGroup() + .addComponent(CHhistory) + .addGap(18, 18, 18) + .addComponent(Cookies)) + .addGroup(layout.createSequentialGroup() + .addComponent(IEhistory) + .addGap(18, 18, 18) + .addComponent(FFhistory)) + .addComponent(jLabel2) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5) + .addGroup(layout.createSequentialGroup() + .addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(6, 6, 6) + .addComponent(jLabel7) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(activityProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(makeNodesButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 7, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel6) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(IEhistory) + .addComponent(FFhistory)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(CHhistory) + .addComponent(Cookies)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(Bookmarks) + .addGap(18, 18, 18) + .addComponent(jLabel4) + .addGap(97, 97, 97) + .addComponent(jLabel5) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7)) + .addGroup(layout.createSequentialGroup() + .addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1)) + .addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(102, Short.MAX_VALUE)) + ); + + IEhistory.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RecentActivityTopComponent.class, "RecentActivityTopComponent.jCheckBox1.AccessibleContext.accessibleName")); // NOI18N + }// </editor-fold>//GEN-END:initComponents + + private void makeNodesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_makeNodesButtonActionPerformed + activityProgressBar.setIndeterminate(true); + edx.makeNodes(); + activityProgressBar.setIndeterminate(false); + + }//GEN-LAST:event_makeNodesButtonActionPerformed + +public void setProgress(int percent){ + activityProgressBar.setValue(percent); +} + +private void IEhistoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_IEhistoryActionPerformed +// TODO add your handling code here: +}//GEN-LAST:event_IEhistoryActionPerformed + +private void dateFromTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateFromTextFieldFocusLost + // set the "from" calendar button to listen to change in the text field + String fromDateString = this.dateFromTextField.getText(); + if (!fromDateString.equals("")) { + try { + Date fromDate = dateFormat.parse(fromDateString); + dateFromButtonCalendar.setTargetDate(fromDate); + } catch (ParseException ex) { + // for now, no need to show the error message to the user her + } + } +}//GEN-LAST:event_dateFromTextFieldFocusLost + +private void dateFromPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateFromPopupChanged + if (evt.getNewValue() instanceof Date) { + setFromDate((Date) evt.getNewValue()); + } +}//GEN-LAST:event_dateFromPopupChanged + +private void dateToPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateToPopupChanged + if (evt.getNewValue() instanceof Date) { + setToDate((Date) evt.getNewValue()); + } +}//GEN-LAST:event_dateToPopupChanged + +private void dateToTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateToTextFieldFocusLost + // set the "to" calendar button to listen to change in the text field + String toDateString = this.dateToTextField.getText(); + if (!toDateString.equals("")) { + try { + Date toDate = dateFormat.parse(toDateString); + dateToButtonCalendar.setTargetDate(toDate); + } catch (ParseException ex) { + // for now, no need to show the error message to the user here + } + } +}//GEN-LAST:event_dateToTextFieldFocusLost + /** + * Validate and set the datetime field on the screen given a datetime string. + * @param date The date object + */ + private void setFromDate(Date date) { + String dateStringResult = ""; + if (date != null) { + dateStringResult = dateFormat.format(date); + } + dateFromTextField.setText(dateStringResult); + dateFromButtonCalendar.setTargetDate(date); + } + + /** + * Validate and set the datetime field on the screen given a date. + * @param date The date object + */ + private void setToDate(Date date) { + String dateStringResult = ""; + if (date != null) { + dateStringResult = dateFormat.format(date); + } + dateToTextField.setText(dateStringResult); + dateToButtonCalendar.setTargetDate(date); + } + + /** + * Set the counts and populate the browser checkboxes which will be used to filter + */ + private int FFcount = 0; + private int IEcount = 0; + private int CHcount = 0; + private int Cookiescount = 0; + private int Bookmarkcount = 0; + public void setbrowsercheckboxes(int IEcount, int FFcount, int CHcount, int Cookiescount, int Bookmarkcount) { + IEhistory.setText("IE History (" + IEcount +")"); + FFhistory.setText("Firefox History (" + FFcount +")"); + CHhistory.setText("Chrome History (" + CHcount +")"); + Cookies.setText("All Cookies (" + Cookiescount +")"); + Bookmarks.setText("All Bookmarks (" + Bookmarkcount +")"); + + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox Bookmarks; + private javax.swing.JCheckBox CHhistory; + private javax.swing.JCheckBox Cookies; + private javax.swing.JCheckBox FFhistory; + private javax.swing.JCheckBox IEhistory; + private javax.swing.JProgressBar activityProgressBar; + private org.sourceforge.jcalendarbutton.JCalendarButton dateFromButtonCalendar; + private javax.swing.JFormattedTextField dateFromTextField; + private org.sourceforge.jcalendarbutton.JCalendarButton dateToButtonCalendar; + private javax.swing.JFormattedTextField dateToTextField; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JList jList2; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JSeparator jSeparator1; + private javax.swing.JTextField jTextField1; + private javax.swing.JButton makeNodesButton; + // End of variables declaration//GEN-END:variables +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java new file mode 100644 index 0000000000000000000000000000000000000000..2b8070b11080e464a6a1df6c503afbe9962d6170 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java @@ -0,0 +1,60 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; +import java.io.File; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.SleuthkitCase; +/** + * + * @author Alex + */ +public class Util { +public Logger logger = Logger.getLogger(this.getClass().getName()); + + private Util(){ + + } + +public static boolean pathexists(String path){ + File file=new File(path); + boolean exists = file.exists(); + return exists; +} + +public static boolean imgpathexists(String path){ + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + + int count = 0; + try { + List<FsContent> FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where parent_path LIKE '%"+ path + "%'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + count = FFSqlitedb.size(); + } + catch (SQLException ex) + { + //logger.log(Level.WARNING, "Error while trying to contact SQLite db.", ex); + } + finally { + + if(count > 0) + { + return true; + } + else + { + return false; + } + } + + } +} \ No newline at end of file diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/dbconnect.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/dbconnect.java new file mode 100644 index 0000000000000000000000000000000000000000..b3f127e900fb314eed37c3da11338e59130f6a2d --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/dbconnect.java @@ -0,0 +1,25 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.sql.*; +/** + * + * @author Alex + */ + public class dbconnect extends sqlitedbconnect{ + + private String sDriverForclass = "org.sqlite.JDBC"; + public dbconnect(String sDriverForClass, String sUrlKey) throws Exception + { + init(sDriverForClass, sUrlKey); + Statement stmt = conn.createStatement(); + //String selecthistory = "SELECT moz_historyvisits.id,url,title,visit_count,visit_date,from_visit,rev_host FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id AND hidden = 0"; + // ResultSet rs = stmt.executeQuery(selecthistory); + + } + + + } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/layer.xml b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/layer.xml new file mode 100644 index 0000000000000000000000000000000000000000..40f6e5e00b945a031f5d6ba2afa590e0f35a5728 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/layer.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd"> +<filesystem/> diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/sqlitedbconnect.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/sqlitedbconnect.java new file mode 100644 index 0000000000000000000000000000000000000000..59e1f1c557dcba2923d6bd85cbefde8148d33b89 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/sqlitedbconnect.java @@ -0,0 +1,102 @@ +/* + * General C&P class that we need to figure out a better way to integrate, replace after demo + */ +package org.sleuthkit.autopsy.recentactivity; + +/** + * + * @author Alex + */ + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + + +/** Database connection class & utilities **/ + +abstract class sqlitedbconnect { + +public String sDriver = ""; +public String sUrl = null; +public int iTimeout = 30; +public Connection conn = null; +public Statement statement = null; + + +/* Stub constructor for quick instantiation o/t fly for using some of the ancillary stuff */ + +public sqlitedbconnect() +{} + +/* quick and dirty constructor to test the database passing the DriverManager name and the fully loaded url to handle */ +/* NB this will typically be available if you make this class concrete and not abstract */ +public sqlitedbconnect(String sDriverToLoad, String sUrlToLoad) throws Exception +{ +init(sDriverToLoad, sUrlToLoad); +} + +public void init(String sDriverVar, String sUrlVar) throws Exception +{ +setDriver(sDriverVar); +setUrl(sUrlVar); +setConnection(); +setStatement(); +} + +private void setDriver(String sDriverVar) +{ +sDriver = sDriverVar; +} + +private void setUrl(String sUrlVar) +{ +sUrl = sUrlVar; +} + +public void setConnection() throws Exception { +Class.forName(sDriver); +conn = DriverManager.getConnection(sUrl); +} + + +public Connection getConnection() { +return conn; +} + +public void setStatement() throws Exception { +if (conn == null) { +setConnection(); +} +statement = conn.createStatement(); +statement.setQueryTimeout(iTimeout); // set timeout to 30 sec. +} + +public Statement getStatement() { +return statement; +} + +public void executeStmt(String instruction) throws SQLException { +statement.executeUpdate(instruction); +} + +// processes an array of instructions e.g. a set of SQL command strings passed from a file +//NB you should ensure you either handle empty lines in files by either removing them or parsing them out +// since they will generate spurious SQLExceptions when they are encountered during the iteration.... +public void executeStmt(String[] instructionSet) throws SQLException { +for (int i = 0; i < instructionSet.length; i++) { +executeStmt(instructionSet[i]); +} +} + +public ResultSet executeQry(String instruction) throws SQLException { +return statement.executeQuery(instruction); +} + +public void closeConnection() { +try { conn.close(); } catch (Exception ignore) {} +} + +} \ No newline at end of file diff --git a/nbproject/project.properties b/nbproject/project.properties index 4acb2e5e05bca9380be26edfe6add618e6bbaca2..392e98bff729cef7b06a2a562dbdf9d4884e3929 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -20,7 +20,10 @@ modules=\ ${project.org.sleuthkit.autopsy.keywordsearch}:\ ${project.org.sleuthkit.autopsy.coreutils}:\ ${project.org.sleuthkit.autopsy.ingest}:\ - ${project.org.sleuthkit.autopsy.hashdatabase} + ${project.org.sleuthkit.autopsy.hashdatabase}:\ + ${project.org.gnu.trove}:\ + ${project.org.sleuthkit.autopsy.recentactivity} +project.org.gnu.trove=trove project.org.sleuthkit.autopsy.casemodule=Case project.org.sleuthkit.autopsy.corecomponentinterfaces=CoreComponentInterfaces project.org.sleuthkit.autopsy.corecomponents=CoreComponents @@ -32,3 +35,4 @@ project.org.sleuthkit.autopsy.ingest=Ingest project.org.sleuthkit.autopsy.keywordsearch=KeywordSearch project.org.sleuthkit.autopsy.menuactions=MenuActions project.org.sleuthkit.autopsy.datamodel=DataModel +project.org.sleuthkit.autopsy.recentactivity=RecentActivity diff --git a/thirdparty/pasco2/.classpath b/thirdparty/pasco2/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..7bd109d7a131124e8ab9c99dff1e677247a328b4 --- /dev/null +++ b/thirdparty/pasco2/.classpath @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="test"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry exported="true" kind="lib" path="lib/commons-cli-1.0.jar"/> + <classpathentry exported="true" kind="lib" path="lib/commons-collections-3.1.jar"/> + <classpathentry exported="true" kind="lib" path="lib/ctypes4j.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> + <classpathentry exported="true" kind="lib" path="lib/ctypes4j.zip"/> + <classpathentry kind="lib" path="C:/Development/42six/trunk/thirdparty/pasco2/lib/trove-3.0.2.jar"/> + <classpathentry kind="output" path="build"/> +</classpath> diff --git a/thirdparty/pasco2/.project b/thirdparty/pasco2/.project new file mode 100644 index 0000000000000000000000000000000000000000..454c782dbe93e1c2f1d2eb380504a90ee7423dfa --- /dev/null +++ b/thirdparty/pasco2/.project @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>pasco2</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> + <linkedResources> + <link> + <name>lib</name> + <type>2</type> + <location>C:/Development/42six/trunk/thirdparty/pasco2/lib</location> + </link> + </linkedResources> + <variableList> + <variable> + <name>BIN_DIR</name> + <value>file:/C:/Development/42six/trunk/thirdparty/pasco2/bin</value> + </variable> + </variableList> +</projectDescription> diff --git a/thirdparty/pasco2/.settings/org.eclipse.jdt.core.prefs b/thirdparty/pasco2/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..e43bcbde9059e920649c7e9181ee7666689022c8 --- /dev/null +++ b/thirdparty/pasco2/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,292 @@ +#Thu Dec 29 15:00:31 MST 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=mixed +org.eclipse.jdt.core.formatter.tabulation.size=8 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/thirdparty/pasco2/.settings/org.eclipse.jdt.ui.prefs b/thirdparty/pasco2/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000000000000000000000000000000000000..fa8570c5ec91dd7145b54a51069686378b94d667 --- /dev/null +++ b/thirdparty/pasco2/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,6 @@ +#Thu Dec 29 15:00:31 MST 2011 +eclipse.preferences.version=1 +formatter_profile=org.eclipse.jdt.ui.default.sun_profile +formatter_settings_version=12 +org.eclipse.jdt.ui.javadoc=false +org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates> diff --git a/thirdparty/pasco2/build.xml b/thirdparty/pasco2/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..f1f1d01e52a8335183c005c591ae3de11e250702 --- /dev/null +++ b/thirdparty/pasco2/build.xml @@ -0,0 +1,94 @@ +<project name="pasco2" default="jar" basedir="."> + + <!-- paths --> + <property file="${basedir}/build.properties"/> + <property name="src.dir" location="${basedir}/src"/> + <property name="java.src.dir" location="${basedir}/src"/> + <property name="java.test.dir" location="${basedir}/src/test"/> + <property name="doc.dir" location="${basedir}/doc"/> + + <property name="bin.dir" location="${basedir}/bin"/> + <property name="dist.dir" location="${basedir}/dist"/> + <property name="lib.dir" value="${basedir}/lib"/> + <property name="build.dir" location="${basedir}/build"/> + <property name="build.lib.dir" location="${basedir}/lib/build"/> + + + <!-- build / compile properties --> + <property name="debug" value="off"/> + <property name="optimize" value="on"/> + <property name="deprecation" value="off"/> + <property name="compress.jars" value="true"/> + <property name="link" value="static"/> + + + <path id="project.class.path"> + <pathelement path="${java.class.path}" /> + <fileset dir="${lib.dir}"> + <include name="*.jar" /> + </fileset> + </path> + + <path id="build.class.path"> + <pathelement path="${java.class.path}" /> + <fileset dir="${lib.dir}"> + <include name="*.jar" /> + </fileset> + </path> + + <target name="init"> + <tstamp/> + <mkdir dir="${build.dir}"/> + <mkdir dir="${dist.dir}"/> + </target> + + <target name="compile" depends="init" + description="compile the source " > + <javac srcdir="${java.src.dir}" + destdir="${build.dir}" + debug="${debug}" + optimize="${optimize}" + deprecation="${deprecation}" + target="1.5" + source="1.5" + includeantruntime="false"> + <classpath refid="project.class.path" /> + <compilerarg value="-Xlint:unchecked,-options"/> + </javac> + </target> + + + + <target name="jar" depends="compile"> + <jar jarfile="${dist.dir}/pasco2.jar" + basedir="${build.dir}" + includes="**/*.class,**/*.properties,**/*.bmp,**/*.gif,${lib.dir}/*.jar"> + <manifest> + <attribute name="Main-Class" + value="isi.pasco2.Main"/> + </manifest> + </jar> + </target> + + <target name="dist" depends="jar"> + <zip destfile="${dist.dir}/pasco2-0.1.zip"> + <zipfileset prefix="lib" dir="${lib.dir}" /> + <zipfileset prefix="src" dir="${src.dir}" /> + <zipfileset dir="${dist.dir}"> + <include name="*.jar"/> + </zipfileset> + <zipfileset file="LICENSE.txt" /> + <zipfileset file="LICENSE-jawin.txt" /> + <zipfileset file="README.txt" /> + <zipfileset file="build.xml" /> + </zip> + </target> + + + <target name="clean" + description="clean up" > + <delete dir="${build.dir}"/> + <delete dir="${dist.dir}"/> + </target> + +</project> diff --git a/thirdparty/pasco2/lib/commons-cli-1.0.jar b/thirdparty/pasco2/lib/commons-cli-1.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..22a004e14e16720cae9af97d4d1475b12d2388aa Binary files /dev/null and b/thirdparty/pasco2/lib/commons-cli-1.0.jar differ diff --git a/thirdparty/pasco2/lib/commons-collections-3.1.jar b/thirdparty/pasco2/lib/commons-collections-3.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..41e230feeaa53618b6ac5f8d11792c2eecf4d4fd Binary files /dev/null and b/thirdparty/pasco2/lib/commons-collections-3.1.jar differ diff --git a/thirdparty/pasco2/lib/ctypes4j.dll b/thirdparty/pasco2/lib/ctypes4j.dll new file mode 100644 index 0000000000000000000000000000000000000000..3455ad1771c222ac7181c4849ce52bf61f9365d2 Binary files /dev/null and b/thirdparty/pasco2/lib/ctypes4j.dll differ diff --git a/thirdparty/pasco2/lib/ctypes4j.jar b/thirdparty/pasco2/lib/ctypes4j.jar new file mode 100644 index 0000000000000000000000000000000000000000..a6c6f3c3b0e1db8e5d7e9214fc0a5ad839f70282 Binary files /dev/null and b/thirdparty/pasco2/lib/ctypes4j.jar differ diff --git a/thirdparty/pasco2/lib/ctypes4j.zip b/thirdparty/pasco2/lib/ctypes4j.zip new file mode 100644 index 0000000000000000000000000000000000000000..84d28c2dbaeb508642386804b2f7916029070a9a Binary files /dev/null and b/thirdparty/pasco2/lib/ctypes4j.zip differ diff --git a/thirdparty/pasco2/lib/pasco2.jar b/thirdparty/pasco2/lib/pasco2.jar new file mode 100644 index 0000000000000000000000000000000000000000..1f07a5e960e13be471f0eaabe6dae4b9d5f4261a Binary files /dev/null and b/thirdparty/pasco2/lib/pasco2.jar differ diff --git a/thirdparty/pasco2/lib/trove-1.0.2.jar b/thirdparty/pasco2/lib/trove-1.0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..ac62eb35cdb4904289d49b6d322c6b0ebc97a2b4 Binary files /dev/null and b/thirdparty/pasco2/lib/trove-1.0.2.jar differ diff --git a/thirdparty/pasco2/lib/trove-3.0.2.jar b/thirdparty/pasco2/lib/trove-3.0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..12fb57681f8ca343350c8f43f1a8c007045936ec Binary files /dev/null and b/thirdparty/pasco2/lib/trove-3.0.2.jar differ diff --git a/thirdparty/pasco2/src/isi/pasco2/Main.java b/thirdparty/pasco2/src/isi/pasco2/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..a16914e90843251cc879e28f84120cdd26e9e2a1 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/Main.java @@ -0,0 +1,187 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +package isi.pasco2; + +import isi.pasco2.handler.CountingCacheHandler; +import isi.pasco2.handler.Pasco2HistoryHandler; +import isi.pasco2.io.FastReadIndexFile; +import isi.pasco2.io.IndexFile; +import isi.pasco2.parser.IECacheFileParser; +import isi.pasco2.parser.IEHistoryFileParser; +import isi.pasco2.parser.IEIndexFileParser; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; + +/** + * Main command line parser for pasco2 + * + * @author Bradley Schatz + * + */ +public class Main { + public static void main(String[] args) { + CommandLineParser parser = new PosixParser(); + + Options options = new Options(); + Option undelete = new Option("d", "Undelete activity records"); + options.addOption(undelete); + Option disableAllocation = new Option("M", "Disable allocation detection"); + options.addOption(disableAllocation); + Option fieldDelimeter = OptionBuilder.withArgName( "field-delimeter" ) + .hasArg() + .withDescription( "Field Delimeter (TAB by default)" ) + .create( "t" ); + options.addOption(fieldDelimeter); + + Option timeFormat = OptionBuilder.withArgName( "time-format" ) + .hasArg() + .withDescription( "xsd or standard (pasco1 compatible)" ) + .create( "f" ); + options.addOption(timeFormat); + + Option fileTypeOption = OptionBuilder.withArgName( "file-type" ) + .hasArg() + .withDescription( "The type of file: cache or history" ) + .create( "T" ); + + options.addOption(fileTypeOption); + + + try { + CommandLine line = parser.parse( options, args ); + boolean undeleteMethod = false; + String delimeter = null; + String format = null; + String fileType = null; + boolean disableAllocationTest = false; + + if( line.hasOption( "d" ) ) { + undeleteMethod = true; + } + + if( line.hasOption( 't' ) ) { + delimeter = line.getOptionValue( 't' ) ; + } + + if( line.hasOption( 'M' ) ) { + disableAllocationTest = true ; + } + + if( line.hasOption( 'T' ) ) { + fileType = line.getOptionValue( 'T' ) ; + } + + if( line.hasOption( 'f' ) ) { + format = line.getOptionValue( 'f' ) ; + } + + if (line.getArgs().length != 1) { + System.err.println("No file specified."); + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp( "pasco2", options ); + System.exit(1); + } + String fileName = line.getArgs()[0]; + + try { + IndexFile fr = new FastReadIndexFile(fileName, "r"); + + CountingCacheHandler handler = null; + + if (fileType == null) { + handler = new CountingCacheHandler(); + } + if (fileType == null) { + handler = new CountingCacheHandler(); + } else if (fileType.equals("cache")) { + handler = new CountingCacheHandler(); + } else if (fileType.equals("history")) { + handler = new Pasco2HistoryHandler(); + } + + if (format != null) { + if (format.equals("pasco")) { + DateFormat regularDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS"); + handler.setDateFormat(regularDateFormat); + TimeZone tz = TimeZone.getTimeZone("Australia/Brisbane"); + regularDateFormat.setTimeZone(tz); + + } else if (format.equals("standard")) { + DateFormat xsdDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + handler.setDateFormat(xsdDateFormat); + xsdDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } else { + System.err.println("Format not supported."); + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp( "pasco2", options ); + System.exit(1); + } + } + + if (delimeter != null) { + handler.setDelimeter(delimeter); + } + + IEIndexFileParser logparser = null; + if (fileType == null) { + System.err.println("Using cache file parser."); + logparser = new IECacheFileParser(fileName, fr, handler); + } else if (fileType.equals("cache")) { + logparser = new IECacheFileParser(fileName, fr, handler); + } else if (fileType.equals("history")) { + logparser = new IEHistoryFileParser(fileName, fr, handler); + } else { + System.err.println("Unsupported file type."); + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp( "pasco2", options ); + System.exit(1); + } + if (disableAllocationTest) { + logparser.setDisableAllocationTest(true); + } + logparser.parseFile(); + + } catch (Exception ex) { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + } + + } + catch( ParseException exp ) { + System.out.println( "Unexpected exception:" + exp.getMessage() ); + } + } +} + + diff --git a/thirdparty/pasco2/src/isi/pasco2/Poller.java b/thirdparty/pasco2/src/isi/pasco2/Poller.java new file mode 100644 index 0000000000000000000000000000000000000000..776263f2184a27eaae2188afc12c05e945e1e069 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/Poller.java @@ -0,0 +1,75 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +package isi.pasco2; + +import isi.pasco2.io.FastReadIndexFile; +import isi.pasco2.io.IndexFile; +import isi.pasco2.parser.IEHistoryFileParser; +import isi.pasco2.poller.DifferenceHandler; + +/** + * Index.dat difference observer. Periodically polls the index.dat file in question and + * notes and changes. + * + * Limitations: Very memory intensive, should watch the unknown sections better. + * + * @author Bradley Schatz + * + */ +public class Poller { + public static void main(String[] args) { + String cachePath = "d:\\Documents and Settings\\bschatz\\Local Settings\\Temporary Internet Files\\Content.IE5\\index.dat"; + String historyPath = "d:\\Documents and Settings\\bschatz\\Local Settings\\History\\History.IE5\\index.dat"; + + //DifferenceHandler cacheHandler = new DifferenceHandler("Cache"); + DifferenceHandler historyHandler = new DifferenceHandler("History"); + + //IEIndexFileParser cacheparser = new IEIndexFileParser(); + IEHistoryFileParser historyParser ; + + while (true) { + try { + //IndexFile f1 = new FastReadIndexFile(cachePath); + //cacheparser.parseFile(cachePath, f1, cacheHandler); + //f1.close(); + + IndexFile f2 = new FastReadIndexFile(historyPath); + historyParser = new IEHistoryFileParser(cachePath, f2, historyHandler); + historyParser.parseFile(); + f2.close(); + + try { + Thread.sleep(10000); + } catch (InterruptedException ex) { + } + } catch (Exception ex) { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + } + + } + + } +} + + diff --git a/thirdparty/pasco2/src/isi/pasco2/handler/AbstractPrinterHandler.java b/thirdparty/pasco2/src/isi/pasco2/handler/AbstractPrinterHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..19e85c208c47ebd094862242b602b775a921a393 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/handler/AbstractPrinterHandler.java @@ -0,0 +1,156 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +package isi.pasco2.handler; + + +import isi.pasco2.parser.DateTime; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class AbstractPrinterHandler implements DefaultHandler { + Writer output; + String delimeter = "\t"; + DateFormat dateFormat = null; + + + public String getDelimeter() { + return delimeter; + } + + public void setDelimeter(String seperator) { + this.delimeter = seperator; + } + + public AbstractPrinterHandler(Writer w) { + output = w; + dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + public AbstractPrinterHandler(Writer w, DateFormat df) { + output = w; + dateFormat = df; + } + + public AbstractPrinterHandler() { + output = new PrintWriter(System.out); + dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + public void endDocument() { + try { + output.close(); + } catch (IOException ex) { + handleException(ex); + } + } + + + + public void LEAKRecord(DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders) { + try { + output.write("LEAK"); + output.write(delimeter); + output.write(url); + output.write(delimeter); + output.write(dateFormat.format(modTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(accessTime.asDate())); + output.write(delimeter); + output.write(file); + output.write(delimeter); + output.write(directory); + output.write(delimeter); + output.write(removeNewlines(httpHeaders)); + output.write("\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + + public void REDRRecord(String url) { + try { + output.write("REDR" + delimeter + url + "\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + + + public void startDocument(String fileName, float version) { + try { + output.write("History File: " + fileName + " Version: " + Float.toString(version) + "\r\n\r\n"); + output.write("TYPE" + delimeter + "URL" + delimeter + "MODIFIED TIME" + delimeter + "ACCESS TIME" + delimeter + "FILENAME" + delimeter + "DIRECTORY" + delimeter + "HTTP HEADERS\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + + + + public void invalidRecord(int offset) { + try { + output.write("Inconsistent record " + Integer.toHexString(offset) + "\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + + public void unknownRecord(String type, int offset, byte[] record) { + try { + output.write("Unknown record type at offset: " + Integer.toHexString(offset) + "\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + protected void handleException(Exception ex) { + ex.printStackTrace(); + } + + String removeNewlines(String str) { + return str.replaceAll("\r\n", " "); + } + + public DateFormat getDateFormat() { + return dateFormat; + } + + public void setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + public void unusedRecord(int offset) { + } + + public void record(int offset, byte[] rec) { + } + + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/handler/CacheAccessHandler.java b/thirdparty/pasco2/src/isi/pasco2/handler/CacheAccessHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..c773bec98b3bbf40880a3eef0151088a11e8aed7 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/handler/CacheAccessHandler.java @@ -0,0 +1,31 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +package isi.pasco2.handler; + +import isi.pasco2.parser.DateTime; + +public interface CacheAccessHandler extends DefaultHandler { + public void LEAKRecord(DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders); + public void URLRecord(DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders); + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/handler/CountingCacheHandler.java b/thirdparty/pasco2/src/isi/pasco2/handler/CountingCacheHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..2adc115536278a2623446e902de9e3cc1b776314 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/handler/CountingCacheHandler.java @@ -0,0 +1,92 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.handler; + +import isi.pasco2.parser.DateTime; +import isi.pasco2.parser.time.FileTime; +import isi.pasco2.util.HexFormatter; + +import java.io.IOException; + +public class CountingCacheHandler extends Pasco2CacheHandler { + int LEAKcount = 0; + int URLcount = 0; + int REDRcount = 0; + int ENTcount = 0; + int unknowncount = 0; + + public void unknownRecord(String type, int offset, byte[] record) { + try { + if (type.startsWith("ent")) { + ENTcount += 1; + } else { + unknowncount += 1; + } + output.write("Unknown record type at offset: " + Integer.toHexString(offset) + "\r\n"); + output.write(HexFormatter.convertBytesToString(record)); + output.write("\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + + public void endDocument() { + try { + output.write("LEAK entries: " + Integer.toString(LEAKcount) + "\r\n"); + output.write("REDR entries: " + Integer.toString(REDRcount) + "\r\n"); + output.write("URL entries: " + Integer.toString(URLcount) + "\r\n"); + output.write("ent entries: " + Integer.toString(ENTcount) + "\r\n"); + output.write("unknown entries: " + Integer.toString(unknowncount) + "\r\n"); + + } catch (IOException ex) { + handleException(ex); + } + super.endDocument(); + + } + + + public void LEAKRecord(FileTime accessTime, FileTime modTime, String url, String file, String directory, String httpHeaders) { + LEAKcount += 1; + super.LEAKRecord(accessTime, modTime, url, file, directory, httpHeaders); + } + + public void REDRRecord(String url) { + REDRcount += 1; + super.REDRRecord(url); + } + + public void URLRecord(FileTime accessTime, FileTime modTime, String url, String file, String directory, String httpHeaders) { + URLcount += 1; + super.URLRecord(accessTime, modTime, url, file, directory, httpHeaders); + } + + public void URLRecord(DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders) { + URLcount += 1; + super.URLRecord( localAccessTime, accessTime, modTime, url, file, directory, httpHeaders); + } + + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/handler/DefaultHandler.java b/thirdparty/pasco2/src/isi/pasco2/handler/DefaultHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..a542b7b653dcf834da127df18c976c7d5036888a --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/handler/DefaultHandler.java @@ -0,0 +1,35 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.handler; + + +public interface DefaultHandler { + public void startDocument(String fileName, float version); + public void endDocument(); + public void unknownRecord(String type, int offset, byte[] record); + public void unusedRecord(int offset); + public void invalidRecord(int offset); + public void record(int currentOffset, byte[] rec); + public void REDRRecord(String url); +} diff --git a/thirdparty/pasco2/src/isi/pasco2/handler/HistoryAccessHandler.java b/thirdparty/pasco2/src/isi/pasco2/handler/HistoryAccessHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..5c1b35199547c1f4425538540b1b021c5dfdff89 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/handler/HistoryAccessHandler.java @@ -0,0 +1,32 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.handler; + +import isi.pasco2.parser.DateTime; + +public interface HistoryAccessHandler extends DefaultHandler { + public void URLRecord(DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url); + public void URLRecord(DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url, int numberOfAccesses); + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/handler/Pasco2CacheHandler.java b/thirdparty/pasco2/src/isi/pasco2/handler/Pasco2CacheHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..a99737d9725705fb975b43dfe8cb1743ea74b9ac --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/handler/Pasco2CacheHandler.java @@ -0,0 +1,74 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +package isi.pasco2.handler; + +import isi.pasco2.parser.DateTime; + +import java.io.IOException; + +public class Pasco2CacheHandler extends AbstractPrinterHandler implements CacheAccessHandler { + + public void URLRecord(DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders) { + try { + output.write("URL"); + output.write(delimeter); + output.write(url); + output.write(delimeter); + output.write(dateFormat.format(modTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(accessTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(localAccessTime.asDate())); + output.write(delimeter); + output.write(file); + output.write(delimeter); + output.write(directory); + output.write(delimeter); + output.write(removeNewlines(httpHeaders)); + output.write("\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + + public void URLRecord(DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders) { + try { + output.write("URL"); + output.write(delimeter); + output.write(url); + output.write(delimeter); + output.write(dateFormat.format(modTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(accessTime.asDate())); + output.write(delimeter); + output.write(file); + output.write(delimeter); + output.write(directory); + output.write(delimeter); + output.write(removeNewlines(httpHeaders)); + output.write("\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/handler/Pasco2HistoryHandler.java b/thirdparty/pasco2/src/isi/pasco2/handler/Pasco2HistoryHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..5c3c1667800ef29b144e91b1e6ac6dc49797be17 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/handler/Pasco2HistoryHandler.java @@ -0,0 +1,69 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +package isi.pasco2.handler; + +import isi.pasco2.parser.DateTime; + +import java.io.IOException; + +public class Pasco2HistoryHandler extends CountingCacheHandler implements + HistoryAccessHandler { + public void URLRecord(DateTime localAccessTime, DateTime accessTime, + DateTime modTime, String url, int numberOfAccesses) { + try { + output.write("URL"); + output.write(delimeter); + output.write(url); + output.write(delimeter); + output.write(dateFormat.format(modTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(accessTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(localAccessTime.asDate())); + output.write(delimeter); + output.write(Integer.toString(numberOfAccesses)); + output.write("\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + + public void URLRecord(DateTime localAccessTime, DateTime accessTime, + DateTime modTime, String url) { + try { + output.write("URL"); + output.write(delimeter); + output.write(url); + output.write(delimeter); + output.write(dateFormat.format(modTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(accessTime.asDate())); + output.write(delimeter); + output.write(dateFormat.format(localAccessTime.asDate())); + output.write("\r\n"); + } catch (IOException ex) { + handleException(ex); + } + } + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/io/EnhancedRandomAccessFile.java b/thirdparty/pasco2/src/isi/pasco2/io/EnhancedRandomAccessFile.java new file mode 100644 index 0000000000000000000000000000000000000000..ef5a2ebc726c3a82394c7b1c51918c723cb66d5f --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/io/EnhancedRandomAccessFile.java @@ -0,0 +1,100 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.io; + +import isi.pasco2.util.StructConverter; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +public class EnhancedRandomAccessFile extends RandomAccessFile implements + IndexFile { + public EnhancedRandomAccessFile(File arg0, String arg1) + throws FileNotFoundException { + super(arg0, arg1); + } + + public EnhancedRandomAccessFile(String arg0, String arg1) + throws FileNotFoundException { + super(arg0, arg1); + } + + public int readLittleEndianInt() throws IOException { + byte[] bytes = new byte[4]; + read(bytes, 0, 4); + return StructConverter.bytesIntoInt(bytes, 0); + } + + public long readLittleEndianUInt() throws IOException { + byte[] bytes = new byte[4]; + read(bytes, 0, 4); + return StructConverter.bytesIntoUInt(bytes, 0); + } + + public int readLittleEndianShort() throws IOException { + byte[] bytes = new byte[2]; + read(bytes, 0, 2); + return StructConverter.bytesIntoShort(bytes, 0); + } + + void debug(byte[] bytes, int len) { + for (int i = 0; i < len; i++) { + System.out.print(Byte.toString(bytes[i]) + " "); + } + System.out.println(); + } + + public char readAsciiChar() throws IOException { + byte b = readByte(); + return (char) b; + } + + public String readStringAtOffset(long offset, int length) throws IOException { + seek(offset); + byte[] dn = new byte[length]; + read(dn, 0, length); + if (dn[0] == 0) { + return new String(); + } else { + return new String(dn); + } + } + + public int readIntAtOffset(long offset) throws IOException { + seek(offset); + return readLittleEndianInt(); + } + + public long readUIntAtOffset(long offset) throws IOException { + seek(offset); + return readLittleEndianUInt(); + } + + public int readShortAtOffset(long offset) throws IOException { + seek(offset); + return readLittleEndianShort(); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/io/FastReadIndexFile.java b/thirdparty/pasco2/src/isi/pasco2/io/FastReadIndexFile.java new file mode 100644 index 0000000000000000000000000000000000000000..e1e7012689eaa42a75ee3b0627bfd0b2ce1b752d --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/io/FastReadIndexFile.java @@ -0,0 +1,147 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.io; + +import isi.pasco2.util.StructConverter; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +public class FastReadIndexFile implements IndexFile { + ByteBuffer content = null; + + public FastReadIndexFile(String fileName) throws FileNotFoundException, + IOException { + File file = new File(fileName); + + // Create a read-only memory-mapped file + FileChannel roChannel = new RandomAccessFile(file, "r").getChannel(); + ByteBuffer roBuf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, + (int) roChannel.size()); + + byte[] buf = new byte[roBuf.limit()]; + roBuf.get(buf, 0, roBuf.limit()); + content = ByteBuffer.wrap(buf); + roChannel.close(); + } + + public FastReadIndexFile(String fileName, InputStream stream, long len) throws FileNotFoundException, + IOException { + + ByteBuffer roBuf = ByteBuffer.allocate((int)len); + byte[] buf = roBuf.array(); + + int offset = 0; + int res = 0; + while ((res = stream.read(buf, offset, (int)len-offset)) > 0) { + offset = offset + res; + if (offset == len) { + break; + } + } + stream.close(); + content = roBuf; + } + + public FastReadIndexFile(String fileName, String mode) + throws FileNotFoundException, IOException { + this(fileName); + } + + public void seek(long offset) throws IOException { + content.clear(); + content.position((int) offset); + + } + + public int readLittleEndianInt() throws IOException { + byte[] bytes = new byte[4]; + content.get(bytes, 0, 4); + return StructConverter.bytesIntoInt(bytes, 0); + } + + public long readLittleEndianUInt() throws IOException { + byte[] bytes = new byte[4]; + content.get(bytes, 0, 4); + return StructConverter.bytesIntoUInt(bytes, 0); + } + + public int readLittleEndianShort() throws IOException { + byte[] bytes = new byte[2]; + content.get(bytes, 0, 2); + return StructConverter.bytesIntoShort(bytes, 0); + } + + public int read(byte[] buf, int offset, int count) throws IOException { + content.get(buf, offset, count); + return count; + } + + public int read() throws IOException { + return content.get(); + } + + public char readAsciiChar() throws IOException { + return (char) content.get(); + } + + public int readUnsignedByte() throws IOException { + return content.get(); + } + + public void close() throws IOException { + + } + + public String readStringAtOffset(long offset, int length) throws IOException { + seek(offset); + byte[] dn = new byte[length]; + read(dn, 0, length); + if (dn[0] == 0) { + return new String(); + } else { + return new String(dn); + } + } + + public int readIntAtOffset(long offset) throws IOException { + seek(offset); + return readLittleEndianInt(); + } + + public long readUIntAtOffset(long offset) throws IOException { + seek(offset); + return readLittleEndianUInt(); + } + + public int readShortAtOffset(long offset) throws IOException { + seek(offset); + return readLittleEndianShort(); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/io/IndexFile.java b/thirdparty/pasco2/src/isi/pasco2/io/IndexFile.java new file mode 100644 index 0000000000000000000000000000000000000000..1b1762d07055722f099163eafd62845ac3be20da --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/io/IndexFile.java @@ -0,0 +1,44 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.io; + +import java.io.IOException; + +public interface IndexFile { + public void seek(long offset) throws IOException; + public int readLittleEndianInt() throws IOException; + public long readLittleEndianUInt() throws IOException; + public int readLittleEndianShort() throws IOException; + public int read(byte[] buf, int offset, int count) throws IOException; + public int read() throws IOException; + public char readAsciiChar() throws IOException; + public int readUnsignedByte() throws IOException; + public void close() throws IOException; + public String readStringAtOffset(long offset, int length) throws IOException ; + public int readIntAtOffset(long offset) throws IOException; + public long readUIntAtOffset(long offset) throws IOException; + public int readShortAtOffset(long offset) throws IOException; + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/model/REDRRecord.java b/thirdparty/pasco2/src/isi/pasco2/model/REDRRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..cfa288049d1355a012a87027744672141b251d27 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/model/REDRRecord.java @@ -0,0 +1,50 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.model; + +public class REDRRecord extends RecognisedRecord { + public REDRRecord(String url, int offset) { + this.url = url; + this.type = "REDR"; + this.offset = offset; + } + + public boolean equals(Object obj) { + if (obj instanceof REDRRecord) { + REDRRecord rec = (REDRRecord) obj; + if (rec.offset != this.offset) { + return false; + } + if (!rec.url.equals(this.url)) { + return false; + } + } + return true; + } + + + public int hashCode() { + return offset + url.hashCode(); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/model/RecognisedRecord.java b/thirdparty/pasco2/src/isi/pasco2/model/RecognisedRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..90718d5bc9adb1238cba44aa67b6d7b995837ed1 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/model/RecognisedRecord.java @@ -0,0 +1,39 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +package isi.pasco2.model; + +public class RecognisedRecord extends Record { + String url = null; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(type); + sb.append(' '); + if (url != null) { + sb.append(url); + sb.append(' '); + } + + return sb.toString(); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/model/Record.java b/thirdparty/pasco2/src/isi/pasco2/model/Record.java new file mode 100644 index 0000000000000000000000000000000000000000..f6728eef493601e6700b22599bad992916245a5b --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/model/Record.java @@ -0,0 +1,30 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.model; + +public class Record { + String type = null; + int offset; + byte[] buf; +} diff --git a/thirdparty/pasco2/src/isi/pasco2/model/URLLEAKRecord.java b/thirdparty/pasco2/src/isi/pasco2/model/URLLEAKRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..90ac7f3a7f484a9e249ef01b7e4e1acbfab7e47e --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/model/URLLEAKRecord.java @@ -0,0 +1,151 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.model; + +import isi.pasco2.parser.DateTime; +import isi.pasco2.util.HexFormatter; + +public class URLLEAKRecord extends RecognisedRecord { + public String filename = null; + public String httpheaders = null; + public String dirname = null; + public DateTime modTime = null; + public DateTime accessTime = null; + public DateTime localAccessTime = null; + public int accessedCount = 0; + + public URLLEAKRecord(String type, DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders, int offset, byte[] rec) { + this.accessTime = accessTime; + this.modTime = modTime; + this.url = url; + this.filename = file; + this.dirname = directory; + this.httpheaders = httpHeaders; + this.offset = offset; + this.type = type; + this.buf = rec; + } + + public URLLEAKRecord(String type, DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url, String file, String directory, String httpHeaders, int offset, byte[] rec) { + this.accessTime = accessTime; + this.modTime = modTime; + this.url = url; + this.filename = file; + this.dirname = directory; + this.httpheaders = httpHeaders; + this.offset = offset; + this.type = type; + this.buf = rec; + this.localAccessTime = localAccessTime; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(type); + sb.append(" ["); + sb.append(offset); + sb.append("]"); + + if (url != null) { + sb.append(url); + sb.append(' '); + } + if (filename != null) { + sb.append(filename); + sb.append(' '); + } + if (dirname != null) { + sb.append(dirname); + sb.append(' '); + } + if (modTime != null) { + sb.append(modTime.toString()); + sb.append(' '); + } + if (accessTime != null) { + sb.append(accessTime.toString()); + sb.append(' '); + } + if (localAccessTime != null) { + sb.append(localAccessTime.toString()); + sb.append(' '); + } + if (httpheaders != null) { + sb.append(httpheaders); + sb.append(' '); + } + + sb.append("\r\n"); + sb.append(HexFormatter.convertBytesToString(buf)); + + return sb.toString(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof URLLEAKRecord)) { + return false; + } + + URLLEAKRecord rec = (URLLEAKRecord) obj; + if (rec.offset != this.offset) { + return false; + } + if (!rec.modTime.equals(this.modTime)) { + return false; + } + if (!rec.accessTime.equals(this.accessTime)) { + return false; + } + if (!rec.url.equals(this.url)) { + return false; + } + if (rec.filename != null && this.filename == null) { + return false; + } + if (rec.filename == null && this.filename != null) { + return false; + } + if (rec.filename != null && filename != null && !rec.filename.equals(this.filename)) { + return false; + } + if (rec.dirname != null && dirname != null && !rec.dirname.equals(this.dirname)) { + return false; + } + if (rec.httpheaders != null && httpheaders != null && !rec.httpheaders.equals(this.httpheaders)) { + return false; + } + + if (rec.accessedCount != accessedCount) { + return false; + } + return true; + } + + + public int hashCode() { + return offset + filename.hashCode() + httpheaders.hashCode() << 1 + dirname.hashCode() << 2 + modTime.hashCode() << 4 + accessTime.hashCode() << 8; + } + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/model/UnknownRecord.java b/thirdparty/pasco2/src/isi/pasco2/model/UnknownRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..0dcc6e089ed69b4f98b53b8f2a825e6e03d5badf --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/model/UnknownRecord.java @@ -0,0 +1,69 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.model; + +import isi.pasco2.util.HexFormatter; + +import java.io.StringWriter; + +public class UnknownRecord extends Record { + byte[] record; + public UnknownRecord(byte[] record, int offset) { + this.record = record; + this.offset = offset; + } + + public String toString() { + + StringWriter output = new StringWriter(); + output.write("Unknown record type at offset: " + Integer.toHexString(offset) + "\r\n"); + output.write(HexFormatter.convertBytesToString(record)); + output.write("\r\n"); + return output.toString(); + + } + + public boolean equals(Object obj) { + if (obj instanceof UnknownRecord) { + UnknownRecord rec = (UnknownRecord) obj; + if (rec.offset != this.offset) { + return false; + } + if (this.offset != rec.offset) { + return false; + } + if (this.record.length != rec.record.length) { + return false; + } + for (int i=0 ; i < this.record.length ; i++) { + if (rec.record[i] != this.record[i]) { + return false; + } + } + } + return true; + } + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/AbstractValidRecordIterator.java b/thirdparty/pasco2/src/isi/pasco2/parser/AbstractValidRecordIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..b471605ace4c99aa6d938267b7065aaa5c082aca --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/AbstractValidRecordIterator.java @@ -0,0 +1,82 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import gnu.trove.TIntArrayList; + +import java.io.IOException; + +abstract public class AbstractValidRecordIterator implements RecordIterator { + HashBlockIterator hashBlockIt = null ; + HashBlock currentHashBlock = null; + HashRecordIterator hashRecIt = null; + IEIndexFileParser parser; + HashRecord nextRecord = null; + TIntArrayList seenRecords = new TIntArrayList(); + + AbstractValidRecordIterator(IEIndexFileParser parser) throws IOException { + this.parser = parser; + int hashOff = parser.getHashOffset(); + if (hashOff != 0) { + hashBlockIt = parser.getHashBlocks(hashOff); + } + } + + public HashRecord getNextUnclassifiedRecord() throws IOException { + if (hashBlockIt == null) { + return null; + } + if (hashRecIt != null) { + if (hashRecIt.hasNext()) { + return hashRecIt.next(); + } else { + if (hashBlockIt.hasNext()) { + currentHashBlock = hashBlockIt.next(); + hashRecIt = null; + return getNextUnclassifiedRecord(); + } else { + return null; + } + } + } else { + if (currentHashBlock == null) { + if (hashBlockIt.hasNext()) { + currentHashBlock = hashBlockIt.next(); + return getNextUnclassifiedRecord(); + } else { + return null; + } + } else { + hashRecIt = currentHashBlock.getRecords(); + return getNextUnclassifiedRecord(); + } + } + } + + public HashRecord next() { + HashRecord res = nextRecord; + nextRecord = null; + return res; + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/AllRecordIterator.java b/thirdparty/pasco2/src/isi/pasco2/parser/AllRecordIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..a9b5083350f5125a9c40d1f1ba109e4f863e5826 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/AllRecordIterator.java @@ -0,0 +1,58 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import java.io.IOException; + +public class AllRecordIterator extends AbstractValidRecordIterator { + + public AllRecordIterator(IEIndexFileParser parser) throws IOException { + super(parser); + // TODO Auto-generated constructor stub + } + + public boolean hasNext() throws IOException { + if (nextRecord == null) { + while (true) { + nextRecord = getNextUnclassifiedRecord(); + if (nextRecord == null) { + return false; + } else { + if (!nextRecord.containsUnallocatedMemorySignature() + && nextRecord.recordOffset > parser.getHashOffset()) { + if (!seenRecords.contains(nextRecord.recordOffset)) { + if (nextRecord.isAllocated()) { + seenRecords.add(nextRecord.recordOffset); + return true; + } + } + } + nextRecord = null; + } + } + } else { + return true; + } + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/Allocator.java b/thirdparty/pasco2/src/isi/pasco2/parser/Allocator.java new file mode 100644 index 0000000000000000000000000000000000000000..8b32fd502d344e6d05baaa7deabbf48c517ac1cc --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/Allocator.java @@ -0,0 +1,55 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import isi.pasco2.io.IndexFile; + +import java.io.IOException; + +import com.sun.org.apache.xalan.internal.xsltc.dom.BitArray; + + +public class Allocator { + static int allocatorBitMapOffset = 0x250; + IEIndexFileParser parser; + IndexFile file; + public Allocator(IEIndexFileParser parser) { + this.parser = parser; + this.file = parser.indexFile; + } + + public boolean isRecordAllocated(long recordAddress) + throws IOException { + long bitMapIndex = ((recordAddress - parser.getHashOffset()) / 0x80); + long dwordOffset = bitMapIndex / 32; + long bitOffset = bitMapIndex % 32; + + file.seek(allocatorBitMapOffset + dwordOffset * 4); + + int[] bitmap = { file.readLittleEndianInt() }; + BitArray bits = new BitArray(32, bitmap); + + return bits.getBit((int) bitOffset); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/DateTime.java b/thirdparty/pasco2/src/isi/pasco2/parser/DateTime.java new file mode 100644 index 0000000000000000000000000000000000000000..3e158680ed335decc8ade322e3976a93e28f6bfe --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/DateTime.java @@ -0,0 +1,30 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import java.util.Date; + +public interface DateTime { + public Date asDate(); +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/HashBlock.java b/thirdparty/pasco2/src/isi/pasco2/parser/HashBlock.java new file mode 100644 index 0000000000000000000000000000000000000000..59ea4d24a59f77d7d178315e353ded3af9fe4cfa --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/HashBlock.java @@ -0,0 +1,54 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import isi.pasco2.io.IndexFile; + +import java.io.IOException; + +class HashBlock { + int offset; + IndexFile file; + IEIndexFileParser parser; + public static int BLOCK_SIZE = 0x80; + public HashBlock(IndexFile file, IEIndexFileParser parser, int offset) { + this.offset = offset; + this.file = file; + this.parser = parser; + + } + + public int size() throws IOException { + int hashsize = file.readIntAtOffset(offset + 4) * BLOCK_SIZE; + return hashsize; + } + + public int getOffset() { + return offset; + } + + public HashRecordIterator getRecords() throws IOException { + return new HashRecordIterator(this, file, parser.getAllocator()); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/HashBlockIterator.java b/thirdparty/pasco2/src/isi/pasco2/parser/HashBlockIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..0037200377dbc9b360c6881d5c63159b6253a09b --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/HashBlockIterator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import isi.pasco2.io.IndexFile; + +import java.io.IOException; + +class HashBlockIterator { + int offset; + IndexFile file; + boolean started = false; + IEIndexFileParser parser; + + public HashBlockIterator(IndexFile file, IEIndexFileParser parser, int offset) { + this.offset = offset; + this.file = file; + this.parser = parser; + } + + public boolean hasNext() throws IOException { + if (offset != 0) { + return true; + } else { + return false; + } + } + public HashBlock next() throws IOException { + int off = offset; + offset = file.readIntAtOffset(offset + 8); + return new HashBlock(file, parser, off); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/HashRecord.java b/thirdparty/pasco2/src/isi/pasco2/parser/HashRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..d0fdaff55a65b0847e5eb95ef98cb8756acfeb60 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/HashRecord.java @@ -0,0 +1,48 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import java.io.IOException; + +public class HashRecord { + int flags; + int recordOffset; + Allocator allocator; + + public HashRecord(Allocator allocator, int flags, int offset) { + this.flags = flags; + this.recordOffset = offset; + this.allocator = allocator; + } + + public boolean isValid() { + return (flags & 0x0FF) != 0x03 && recordOffset != 0; + } + public boolean containsUnallocatedMemorySignature() { + return recordOffset == 0xBADF00D; + } + public boolean isAllocated() throws IOException { + return allocator.isRecordAllocated(recordOffset); + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/HashRecordIterator.java b/thirdparty/pasco2/src/isi/pasco2/parser/HashRecordIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..4e34c6c34e72517c67b945431abad7883424c9a9 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/HashRecordIterator.java @@ -0,0 +1,60 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + + +import isi.pasco2.io.IndexFile; + +import java.io.IOException; + +public class HashRecordIterator { + int maxBounds; + int offset; + HashBlock hashBlock; + IndexFile file; + Allocator allocator; + + public HashRecordIterator(HashBlock block, IndexFile file, Allocator allocator) throws IOException { + this.hashBlock = block; + this.file = file; + this.allocator = allocator; + maxBounds = hashBlock.getOffset() + hashBlock.size(); + offset = hashBlock.getOffset() + 16; + } + + public boolean hasNext() { + if (offset < maxBounds) { + return true; + } + return false; + } + + public HashRecord next() throws IOException { + int flags = file.readIntAtOffset(offset); + int recordOffset = file.readIntAtOffset( offset + 4); + HashRecord rec = new HashRecord(allocator, flags, recordOffset); + offset += 8; + return rec; + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/IECacheFileParser.java b/thirdparty/pasco2/src/isi/pasco2/parser/IECacheFileParser.java new file mode 100644 index 0000000000000000000000000000000000000000..273e02371868c9bddcb03fa650d44610e5a791ab --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/IECacheFileParser.java @@ -0,0 +1,87 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import isi.pasco2.handler.CacheAccessHandler; +import isi.pasco2.handler.DefaultHandler; +import isi.pasco2.io.IndexFile; +import isi.pasco2.util.StructConverter; + +import java.io.IOException; + +/** + * A parser of index.dat files produced by MS Internet Explorer. This specific class + * parses the history specific elements. + * + * + * Based on: + * * Keith J. Jones's implementation in pasco (http://odessa.sourceforge.net/) + * * Louis K. Thomas' documentated reverse engineering efforts (http://www.latenighthacking.com/projects/2003/reIndexDat/) + * + * @author Bradley Schatz + * + */ +public class IECacheFileParser extends IEIndexFileParser { + + public IECacheFileParser(String fileName, IndexFile file, DefaultHandler handler) { + super(fileName, file, handler); + } + + public IECacheFileParser(String fileName, IndexFile file) { + super(fileName, file); + } + + protected void parseRecord(IndexFile file, int currrecoff, + DefaultHandler handler) throws IOException { + file.seek(currrecoff); + byte[] rec; + CacheAccessHandler cacheHandler = (CacheAccessHandler) handler; + file.seek(currrecoff); + byte[] type = new byte[4]; + file.read(type, 0, 4); + String typeStr = new String(type); + try { + if (typeStr.equals("REDR")) { + parseREDRRecord(file, currrecoff, cacheHandler); + } else if (typeStr.startsWith("URL") || typeStr.equals("LEAK")) { + parseURLLEAKRecord(typeStr, file, currrecoff, cacheHandler); + } else { + int i = StructConverter.bytesIntoInt(type, 0); + if (i == 0x0badf00d) { + // this pattern most likely indicates uninitalized memory as allocated + // by + // a memory allocator. This is probably a mmaped file. + handler.unusedRecord(currrecoff); + } else { + rec = new byte[BLOCK_SIZE]; + file.read(rec, 0, BLOCK_SIZE); + handler.record(currrecoff, rec); + handler.unknownRecord(typeStr, currrecoff, rec); + } + } + } catch (IOException ex) { + handler.invalidRecord(currrecoff); + } + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/IEHistoryFileParser.java b/thirdparty/pasco2/src/isi/pasco2/parser/IEHistoryFileParser.java new file mode 100644 index 0000000000000000000000000000000000000000..b9ab051f65f86549cde529a8727046b9d5e0c8f1 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/IEHistoryFileParser.java @@ -0,0 +1,148 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import isi.pasco2.handler.DefaultHandler; +import isi.pasco2.handler.HistoryAccessHandler; +import isi.pasco2.io.IndexFile; +import isi.pasco2.parser.time.DOSTime; +import isi.pasco2.parser.time.FileTime; +import isi.pasco2.util.StructConverter; + +import java.io.IOException; +import java.util.TimeZone; + +/** + * A parser of index.dat files produced by MS Internet Explorer. This specific class + * parses the history specific elements. + * + * Offsets: + * (+0x00) record start + * (+0x08) FILETIME created time + * (+0x10) FILETIME created time + * (+0x50) 16-bit dos date corresponding to last visit + * (+0x52) 16-bit dos time (UTC) corresponding to last visit + * (+0x54) 32-bit int times visited + * (+0x58) ASCII null terminated string URL + * (+0xBC) Unicode string Page Title + * + * Based on: + * * Keith J. Jones's implementation in pasco (http://odessa.sourceforge.net/) + * * Louis K. Thomas' documentated reverse engineering efforts (http://www.latenighthacking.com/projects/2003/reIndexDat/) + * + * @author Bradley Schatz + * + */ + +public class IEHistoryFileParser extends IEIndexFileParser { + { + // the dos times used in this file are based on UTC + DOSTime.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + public IEHistoryFileParser(String fileName, IndexFile file, + DefaultHandler handler) { + super(fileName, file, handler); + } + + public IEHistoryFileParser(String fileName, IndexFile file) { + super(fileName, file); + } + + protected void parseRecord(IndexFile file, int currrecoff, + DefaultHandler handler) throws IOException { + file.seek(currrecoff); + byte[] rec; + HistoryAccessHandler cacheHandler = (HistoryAccessHandler) handler; + file.seek(currrecoff); + byte[] type = new byte[4]; + file.read(type, 0, 4); + String typeStr = new String(type); + try { + if (typeStr.equals("REDR")) { + parseREDRRecord(file, currrecoff, cacheHandler); + } else if (typeStr.startsWith("URL") || typeStr.equals("LEAK")) { + parseURLLEAKRecord(typeStr, file, currrecoff, cacheHandler); + } else { + int i = StructConverter.bytesIntoInt(type, 0); + if (i == 0x0badf00d) { + // this pattern most likely indicates uninitalized memory as allocated + // by + // a memory allocator. This is probably a mmaped file. + handler.unusedRecord(currrecoff); + } else { + rec = new byte[BLOCK_SIZE]; + file.read(rec, 0, BLOCK_SIZE); + handler.record(currrecoff, rec); + handler.unknownRecord(typeStr, currrecoff, rec); + } + } + } catch (IOException ex) { + handler.invalidRecord(currrecoff); + } + } + + public void parseURLLEAKRecord(String type, IndexFile fr, long currrecoff, + DefaultHandler handler) throws IOException { + int reclen = indexFile.readIntAtOffset(currrecoff + 4) * BLOCK_SIZE; + byte[] rec = new byte[reclen]; + fr.read(rec, 0, reclen); + handler.record((int) currrecoff, rec); + + long low = indexFile.readUIntAtOffset(currrecoff + 8); + long high = fr.readLittleEndianUInt(); + FileTime modTime = new FileTime(low, high); + + low = indexFile.readUIntAtOffset(currrecoff + 16); + high = fr.readLittleEndianUInt(); + FileTime accessTime = new FileTime(low, high); + + int date = indexFile.readShortAtOffset(currrecoff + 0x50); + int time = indexFile.readShortAtOffset(currrecoff + 0x52); + DOSTime lastAccessTime = new DOSTime(date, time); + + int numberOfAccesses = indexFile.readIntAtOffset(currrecoff + 0x54); + + StringBuffer url = readURL(fr, currrecoff); + //StringBuffer filename = readFileName(fr, currrecoff); + //String dirname = readDirName(fr, currrecoff); + //StringBuffer httpheaders = readHTTPHeaders(fr, currrecoff, reclen); + + HistoryAccessHandler h = (HistoryAccessHandler) handler; + if (type.startsWith("URL")) { + h.URLRecord(lastAccessTime, accessTime, modTime, url.toString(), + numberOfAccesses); + } + + // TODO I havent seen a History file with a LEAK record in it yet... but should + // handle this gracefully + + /*else { + handler.LEAKRecord(accessTime, modTime, url.toString(), makePrintable( + filename).toString(), dirname, makePrintable(httpheaders).toString()); + } + */ + } + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/IEIndexFileParser.java b/thirdparty/pasco2/src/isi/pasco2/parser/IEIndexFileParser.java new file mode 100644 index 0000000000000000000000000000000000000000..76364a8749051b1c141357a216253c85cbc60641 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/IEIndexFileParser.java @@ -0,0 +1,333 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import isi.pasco2.handler.AbstractPrinterHandler; +import isi.pasco2.handler.CacheAccessHandler; +import isi.pasco2.handler.DefaultHandler; +import isi.pasco2.io.IndexFile; +import isi.pasco2.parser.time.FileTime; + +import java.io.IOException; + +/** + * A parser of index.dat files produced by MS Internet Explorer. This general class + * parses the elements common to the cache and the history varieties. + * + * Based on: + * * Keith J. Jones's implementation in pasco (http://odessa.sourceforge.net/) + * * Louis K. Thomas' documentated reverse engineering efforts (http://www.latenighthacking.com/projects/2003/reIndexDat/) + * + * @author Bradley Schatz + * + */ +public abstract class IEIndexFileParser { + public static int BLOCK_SIZE = 0x80; + + float version; + + long filesize; + + public int primaryHashOffset; + + String fileName; + + IndexFile indexFile; + + DefaultHandler handler; + + boolean disableAllocationTest = false; + + public IEIndexFileParser(String fileName, IndexFile file, + DefaultHandler handler) { + this.fileName = fileName; + this.indexFile = file; + this.handler = handler; + } + + public IEIndexFileParser(String fileName, IndexFile file) { + this(fileName, file, new AbstractPrinterHandler()); + } + + public void parseFileUsingDeletedMethod(IndexFile file, DefaultHandler handler) + throws IOException { + int currrecoff = 0; + while (currrecoff < filesize) { + parseRecord(file, currrecoff, handler); + currrecoff = currrecoff + BLOCK_SIZE; + } + } + + /* + * Hash Record: (+0x00) 'HASH' (+0x04) # blocks size (+0x08) next hash offset + * (+0x10) first record flags (+0x14) first record offset + */ + public void parseFile() throws IOException { + version = readFileFormatVersion(indexFile); + handler.startDocument(fileName, version); + + long filesize = getFileSize(); + int hashoff = getHashOffset(); + if (hashoff != 0) { + parseHashBlocks(hashoff); + } + handler.endDocument(); + } + + + public HashBlockIterator getHashBlocks(int hashoff) throws IOException { + HashBlockIterator it = new HashBlockIterator(indexFile, this, hashoff); + return it; + } + + public ValidRecordIterator getValidRecords() throws IOException { + return new ValidRecordIterator(this); + } + + public RecordIterator getAllRecords() throws IOException { + return new AllRecordIterator(this); + } + + public void parseHashBlocks(int hashoff) throws IOException { + RecordIterator it; + if (disableAllocationTest) { + it = getAllRecords(); + } else { + it = getValidRecords(); + } + + while (it.hasNext()) { + parseRecord(indexFile, it.next().recordOffset, handler); + } + + } + + public long getFileSize() throws IOException { + indexFile.seek(0x1C); + filesize = indexFile.readLittleEndianInt(); + return filesize; + } + + public int getHashOffset() throws IOException { + int hashoff = indexFile.readIntAtOffset(0x20); + primaryHashOffset = hashoff; + return hashoff; + } + + abstract protected void parseRecord(IndexFile file, int currrecoff, + DefaultHandler handler) throws IOException; + + public void parseURLLEAKRecord(String type, IndexFile fr, long currrecoff, + CacheAccessHandler handler) throws IOException { + int reclen = fr.readIntAtOffset(currrecoff + 4) * BLOCK_SIZE; + byte[] rec = new byte[reclen]; + fr.read(rec, 0, reclen); + + handler.record((int) currrecoff, rec); + + long low = fr.readUIntAtOffset(currrecoff + 8); + long high = fr.readLittleEndianUInt(); + FileTime modTime = new FileTime(low, high); + + low = fr.readUIntAtOffset(currrecoff + 16); + high = fr.readLittleEndianUInt(); + FileTime accessTime = new FileTime(low, high); + + StringBuffer url = readURL(fr, currrecoff); + StringBuffer filename = readFileName(fr, currrecoff); + String dirname = readDirName(fr, currrecoff); + StringBuffer httpheaders = readHTTPHeaders(fr, currrecoff, reclen); + + if (type.startsWith("URL")) { + handler.URLRecord(accessTime, modTime, url.toString(), makePrintable( + filename).toString(), dirname, makePrintable(httpheaders).toString()); + } else { + handler.LEAKRecord(accessTime, modTime, url.toString(), makePrintable( + filename).toString(), dirname, makePrintable(httpheaders).toString()); + } + } + + protected StringBuffer readURL(IndexFile fr, long currrecoff) + throws IOException { + char c; + if (version >= 5) { + fr.seek(currrecoff + 0x34); + } else { + fr.seek(currrecoff + 0x38); + } + + int urloff = fr.readUnsignedByte(); + int i = 0; + fr.seek(currrecoff + urloff); + c = fr.readAsciiChar(); + + StringBuffer url = new StringBuffer(); + + while (c != '\0' && currrecoff + urloff + i + 1 < filesize) { + url.append(c); + fr.seek(currrecoff + urloff + i + 1); + c = fr.readAsciiChar(); + i++; + } + return url; + } + + protected StringBuffer readFileName(IndexFile fr, long currrecoff) + throws IOException { + char c; + int i; + if (version >= 5) { + fr.seek(currrecoff + 0x3C); + } else { + fr.seek(currrecoff + 0x40); + } + long filenameoff = fr.readLittleEndianInt() + currrecoff; + + i = 0; + + StringBuffer filename = new StringBuffer(); + + if (filenameoff > currrecoff + 0x3C) { + fr.seek(filenameoff); + c = fr.readAsciiChar(); + while (c != '\0' && filenameoff + i + 1 < filesize) { + filename.append(c); + fr.seek(filenameoff + i + 1); + c = fr.readAsciiChar(); + i++; + } + } + return filename; + } + + protected StringBuffer readHTTPHeaders(IndexFile fr, long currrecoff, + int reclen) throws IOException { + char c; + int i; + long httpheadersoff; + if (version >= 5) { + httpheadersoff = fr.readIntAtOffset(currrecoff + 0x44) + currrecoff; + + } else { + httpheadersoff = fr.readIntAtOffset(currrecoff + 0x48) + currrecoff; + } + + i = 0; + StringBuffer httpheaders = new StringBuffer(); + if (httpheadersoff > currrecoff + 0x44) { + fr.seek(httpheadersoff); + c = fr.readAsciiChar(); + + while (c != '\0' && httpheadersoff + i + 1 < currrecoff + reclen + && httpheadersoff + i + 1 < filesize) { + httpheaders.append(c); + fr.seek(httpheadersoff + i + 1); + c = fr.readAsciiChar(); + i++; + } + } + return httpheaders; + } + + protected String readDirName(IndexFile fr, long currrecoff) + throws IOException { + char c; + if (version >= 5.2) { + fr.seek(currrecoff + 0x38); + } else if (version >= 5) { + fr.seek(currrecoff + 0x39); + } else { + fr.seek(currrecoff + 0x3C); + } + c = fr.readAsciiChar(); + int dirnameoff = (int) c; + + String dirname; + if (0x50 + (12 * dirnameoff) + 8 < filesize) { + dirname = fr.readStringAtOffset(0x50 + (12 * dirnameoff), 8); + } else { + dirname = new String(); + } + return dirname; + } + + + + public float readFileFormatVersion(IndexFile reader) throws IOException { + reader.seek(0x18); + byte[] versionAry = new byte[3]; + reader.read(versionAry, 0, 3); + reader.read(); + if (versionAry[0] == 0) { + return 0F; + } else { + return Float.parseFloat(new String(versionAry)); + } + } + + void parseREDRRecord(IndexFile fr, long currrecoff, DefaultHandler handler) + throws IOException { + + // int reclen = readIntAtOffset(fr,currrecoff+4 ); + + int i = 0; + fr.seek(currrecoff + 0x10); + char c = fr.readAsciiChar(); + + StringBuffer url = new StringBuffer(); + + while (c != '\0' && currrecoff + 0x10 + i + 1 < filesize) { + url.append(c); + fr.seek(currrecoff + 0x10 + i + 1); + c = fr.readAsciiChar(); + i++; + } + + handler.REDRRecord(url.toString()); + } + + StringBuffer makePrintable(StringBuffer buf) { + for (int i = 0; i < buf.length(); i++) { + char c = buf.charAt(i); + if (((byte) c) < 32 || ((byte) c) > 127) { + buf.setCharAt(i, ' '); + } + } + return buf; + } + + public Allocator getAllocator() { + return new Allocator(this); + } + + public boolean isDisableAllocationTest() { + return disableAllocationTest; + } + + public void setDisableAllocationTest(boolean disableAllocationTest) { + this.disableAllocationTest = disableAllocationTest; + } + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/RecordIterator.java b/thirdparty/pasco2/src/isi/pasco2/parser/RecordIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..a900d8e211750b1bb4ba907c3dbd546d2e13ad5e --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/RecordIterator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import java.io.IOException; + +public interface RecordIterator { + public HashRecord next(); + public boolean hasNext() throws IOException ; +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/ValidRecordIterator.java b/thirdparty/pasco2/src/isi/pasco2/parser/ValidRecordIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..6dbb3d6008104c542a2ccba06aa6461baceb780c --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/ValidRecordIterator.java @@ -0,0 +1,59 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser; + +import java.io.IOException; + +public class ValidRecordIterator extends AbstractValidRecordIterator { + + public ValidRecordIterator(IEIndexFileParser parser) throws IOException { + super(parser); + // TODO Auto-generated constructor stub + } + + public boolean hasNext() throws IOException { + if (nextRecord == null) { + while (true) { + nextRecord = getNextUnclassifiedRecord(); + if (nextRecord == null) { + return false; + } else { + if (nextRecord.isValid() + && !nextRecord.containsUnallocatedMemorySignature() + && nextRecord.recordOffset > parser.getHashOffset()) { + if (!seenRecords.contains(nextRecord.recordOffset)) { + if (nextRecord.isAllocated()) { + seenRecords.add(nextRecord.recordOffset); + return true; + } + } + } + nextRecord = null; + } + } + } else { + return true; + } + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/time/DOSTime.java b/thirdparty/pasco2/src/isi/pasco2/parser/time/DOSTime.java new file mode 100644 index 0000000000000000000000000000000000000000..9b8d40e852b6d1aec2fd7ddfd0e73650847a14c3 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/time/DOSTime.java @@ -0,0 +1,155 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser.time; + +import isi.pasco2.parser.DateTime; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + + +/** + * MS DOS timestamp to java time parser. The MS DOS timestamp is a 32bit timestamp format + * which stores timestamps in those bits as follows: + * bit 0 - 4 : second + * bit 5 - 10 : minute + * bit 11 - 15 : hour + * bit 16 - 20 : day (1-31) + * bit 21 - 24 : month (1-12) + * bit 25 - 31 : year offset from 1980 + * + * Time is based on local time, not UTC + * @author bradley@greystate.com + * + */ +public class DOSTime implements DateTime { + int date; + int time; + + int year; + int month; + int day; + + int hour; + int minute; + int second; + + static TimeZone timeZone = null; + + static DateFormat xsdDateFormat = null; + static DateFormat regularDateFormat = null; + { + xsdDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + xsdDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + regularDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS"); + regularDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + } + +/** + * Construct a DOSTime object from two unsigned words which are read sequentially from + * a DOS timestamp. + * + * @param date a 16bit undigned word, passed as an int as java does not have this type. + * @param time a 16bit undigned word, passed as an int as java does not have this type. + */ + public DOSTime(int date, int time) { + this.date = date; + this.time = time; + parseTime(); + parseDate(); + } + + + void parseTime() { + second = (time & 0x1F) * 2; + minute = (time & 0x7e0) >> 5; + hour = (time & 0xf800) >> 11; + } + + void parseDate() { + day = date & 0x1F; + month = ((date & 0x1e0) >> 5) -1; + year = ((date & 0x3e00) >> 9) + 1980; + } + + public static DOSTime parseLittleEndianHex(String hex) { + assert hex.length() == 8; + + int first = Integer.parseInt(hex.substring(0,4) , 16); + first = ((first & 0xFF) << 8) | ((first & 0x0FF00) >> 8); + + int second = Integer.parseInt(hex.substring(4,8) , 16); + second = ((second & 0xFF) << 8) | ((second & 0x0FF00) >> 8); + + + return new DOSTime(second,first); + } + + public Date asDate() { + Calendar c; + if (timeZone != null) { + c = Calendar.getInstance(timeZone); + } else { + c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + } + c.set(year, month, day, hour, minute, second); + c.set(Calendar.MILLISECOND, 0); + return c.getTime(); + } + + public String toString() { + return xsdDateFormat.format(asDate()); + } + + public boolean equals(Object obj) { + if (obj instanceof DOSTime) { + DOSTime f = (DOSTime) obj; + if (f.date == this.date && f.time == this.time) { + return true; + } + } + return false; + } + + /** + * @return Returns the timeZone. + */ + public static TimeZone getTimeZone() { + return timeZone; + } + + /** + * @param timeZone The timeZone to set. + */ + public static void setTimeZone(TimeZone tz) { + timeZone = tz; + } + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/parser/time/FileTime.java b/thirdparty/pasco2/src/isi/pasco2/parser/time/FileTime.java new file mode 100644 index 0000000000000000000000000000000000000000..163d05c9c2299ea73533361c9b3d94a9c71a4b83 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/parser/time/FileTime.java @@ -0,0 +1,176 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.parser.time; + +import isi.pasco2.parser.DateTime; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class FileTime implements DateTime{ + static DateFormat xsdDateFormat = null; + static DateFormat regularDateFormat = null; + + { + xsdDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + xsdDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + regularDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS"); + regularDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + // the remainder in nanoseconds since the unix epoch + long remainderNanoSeconds; + + // the number of seconds since the unix epoch + long time_t; + + public long gettime_t() { + return time_t; + } + + public long getRemainderNanoSeconds() { + return remainderNanoSeconds; + } + + public long getTimeAsMillis() { + return time_t*1000 + (remainderNanoSeconds / 1000000); + } + + public long getMillisRemainder() { + return remainderNanoSeconds / 1000000; + } + + public long getMicrosRemainder() { + return remainderNanoSeconds % 1000000; + } + + public Date asDate() { + return new Date(getTimeAsMillis()); + } + + private long low; + private long high; + + public long getHigh() { + return high; + } + + public long getLow() { + return low; + } + + /** + * Create a parser for windows FILETIME timestamps. This is a count of the number + * of 100ns increments since the Epoch Jan 1 1601 at 00:00:00. Credits for the + * algorithm go to cygin's to_timestruc_t() implementation found in time.cc. + * + * @param low 32bit unsigned int low value of the timestamp, passed as a java long + * @param high 32bit unsigned int low value of the timestamp, passed as a java long + */ + public FileTime(long low, long high) { + this.low = low; + this.high = high; + parse(low, high); + } + + + // the number of 100 ns ticks between 00:00:00 on Jan 1, 1601 and 00:00:00 Jan 1, 1970 + // validated in the unit test TestPlatform.testSkewBetweenUNIXEpochAndWindowsEpoch + static long skewFILETIME2timetEpochs = 0x19db1ded53e8000L; + static long ticksPerSecond = 10 * 1000 * 1000L; + + /** + * + * this code is based on cygin's times.cc/to_timestruc_t(). Author not indicated. + * + */ + void parse(long low, long high) { + long rem; + long x = (high << 32) + (low); + + /* return the UNIX epoch as the FILETIME epoch */ + if (x == 0) { + time_t = 0; + rem = 0; + return; + } + + x -= skewFILETIME2timetEpochs; // remove the skew so x now is the number of + // ticks since 00:00:00 1/1/1970 + rem = x % ticksPerSecond; // remaining ticks not whole seconds + x /= ticksPerSecond; // number of seconds since UNIX epoch + remainderNanoSeconds = rem * 100; // as remainder is in nanoseconds + time_t = x; + } + + + + public String toString() { + return xsdDateFormat.format(asDate()); + } + + public String toXSDString() { + return xsdDateFormat.format(asDate()); + } + + public String toStandardTime() { + return xsdDateFormat.format(asDate()); + } + + public static FileTime parseLittleEndianHex(String hex) { + assert hex.length() == 16; + + long low = Long.parseLong(hex.substring(0,8) , 16); + low = ((low & 0xFF) << 24) | ((low & 0x0FF00) << 8) | ((low & 0xFF0000) >> 8) | ((low & 0xFF000000)>> 24); + long high = Long.parseLong(hex.substring(8,16) , 16); + high = ((high & 0xFF) << 24) | ((high & 0x0FF00) << 8) | ((high & 0xFF0000) >> 8) | ((high & 0xFF000000)>> 24); + + return new FileTime(low,high); + } + + public static FileTime parseBigEndianHex(String hex) { + assert hex.length() == 16; + + long all = Long.parseLong(hex, 16); + long low = all & 0x0ffffffffL; + long high = (all & 0xffffffff00000000L) >> 32; + + return new FileTime(low,high); + } + + public boolean equals(Object obj) { + if (obj instanceof FileTime) { + FileTime f = (FileTime) obj; + if (f.time_t == this.time_t && f.remainderNanoSeconds == this.remainderNanoSeconds) { + return true; + } + } + return false; + } + + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/poller/DifferenceHandler.java b/thirdparty/pasco2/src/isi/pasco2/poller/DifferenceHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..c79edf4050703aa349f1ed31a8cb10cbc1cc6491 --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/poller/DifferenceHandler.java @@ -0,0 +1,208 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.poller; + +import isi.pasco2.handler.HistoryAccessHandler; +import isi.pasco2.io.IndexFile; +import isi.pasco2.model.REDRRecord; +import isi.pasco2.model.Record; +import isi.pasco2.model.URLLEAKRecord; +import isi.pasco2.model.UnknownRecord; +import isi.pasco2.parser.DateTime; + +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Collection; +import java.util.TimeZone; +import java.util.Vector; + +import org.apache.commons.collections.CollectionUtils; + +public class DifferenceHandler implements HistoryAccessHandler { + SimpleDateFormat xsdDateFormat; + { + xsdDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + xsdDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + } + + Vector<Record> currentUrlRecords = new Vector<Record>(); + Vector<Record> newUrlRecords = new Vector<Record>(); + + boolean initialized = false; + + String name; + int offset; + int length; + byte[] rec; + IndexFile indexFile; + + public DifferenceHandler(String name) { + this.name = name; + } + + public void URLRecord(DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url, + String file, String directory, String httpHeaders) { + URLLEAKRecord u = new URLLEAKRecord("URL", localAccessTime, accessTime, modTime, url, file, + directory, httpHeaders, offset, rec); + if (initialized) { + if (!newUrlRecords.contains(u)) { + newUrlRecords.add(u); + } + } else { + if (!currentUrlRecords.contains(u)) { + currentUrlRecords.add(u); + } + } + } + + public void URLRecord(DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url, int count) { + URLLEAKRecord u = new URLLEAKRecord("URL", localAccessTime, accessTime, modTime, url, null, null, null, offset, rec); + u.accessedCount = count; + if (initialized) { + if (!newUrlRecords.contains(u)) { + newUrlRecords.add(u); + } + } else { + if (!currentUrlRecords.contains(u)) { + currentUrlRecords.add(u); + } + } + } + + public void URLRecord(DateTime localAccessTime, DateTime accessTime, DateTime modTime, String url) { + URLLEAKRecord u = new URLLEAKRecord("URL", localAccessTime, accessTime, modTime, url, null, null, null, offset, rec); + + if (initialized) { + if (!newUrlRecords.contains(u)) { + newUrlRecords.add(u); + } + } else { + if (!currentUrlRecords.contains(u)) { + currentUrlRecords.add(u); + } + } + } + public void URLRecord(DateTime accessTime, DateTime modTime, String url, + String file, String directory, String httpHeaders) { + URLLEAKRecord u = new URLLEAKRecord("URL", accessTime, modTime, url, file, + directory, httpHeaders, offset, rec); + if (initialized) { + if (!newUrlRecords.contains(u)) { + newUrlRecords.add(u); + } + } else { + if (!currentUrlRecords.contains(u)) { + currentUrlRecords.add(u); + } + } + } + + + public void startDocument(String fileName, float version) { + } + + public void endDocument() { + if (!initialized) { + // it is now + initialized = true; + } else { + Collection<Record> deletedRecords = CollectionUtils.subtract( + currentUrlRecords, newUrlRecords); + Collection<Record> newRecords = CollectionUtils.subtract(newUrlRecords, + currentUrlRecords); + + if (deletedRecords.size() > 0 || newRecords.size() > 0) { + StringWriter outWriter = new StringWriter(); + outWriter.write(name + "\r\n"); + for (Record rec : newRecords) { + Calendar c = Calendar.getInstance(); + outWriter.write("New record: (" + xsdDateFormat.format(c.getTime()) + rec.toString() + "\r\n"); + } + for (Record rec : deletedRecords) { + outWriter.write("Deleted record: " + rec.toString() + "\r\n"); + } + + System.out.println(outWriter.toString()); + } + currentUrlRecords = newUrlRecords; + newUrlRecords = new Vector<Record>(); + } + } + + public void invalidRecord(int offset) { + + } + + public void LEAKRecord(DateTime accessTime, DateTime modTime, String url, + String file, String directory, String httpHeaders) { + URLLEAKRecord u = new URLLEAKRecord("LEAK", accessTime, modTime, url, file, + directory, httpHeaders, offset, rec); + if (initialized) { + if (!newUrlRecords.contains(u)) { + newUrlRecords.add(u); + } + } else { + if (!currentUrlRecords.contains(u)) { + currentUrlRecords.add(u); + } + } + } + + public void REDRRecord(String url) { + REDRRecord u = new REDRRecord(url, offset); + if (initialized) { + if (!newUrlRecords.contains(u)) { + newUrlRecords.add(u); + } + } else { + if (!currentUrlRecords.contains(u)) { + currentUrlRecords.add(u); + } + } + } + + public void unknownRecord(String type, int offset, byte[] record) { + UnknownRecord u = new UnknownRecord(record, offset); + if (initialized) { + if (!newUrlRecords.contains(u)) { + newUrlRecords.add(u); + } + } else { + if (!currentUrlRecords.contains(u)) { + currentUrlRecords.add(u); + } + } + } + + public void unusedRecord(int offset) { + } + + public void record(int currentOffset, byte[] rec) { + this.offset = offset; + this.rec = rec; + this.length = length; + } +} diff --git a/thirdparty/pasco2/src/isi/pasco2/util/HexFormatter.java b/thirdparty/pasco2/src/isi/pasco2/util/HexFormatter.java new file mode 100644 index 0000000000000000000000000000000000000000..897dbf3ed577b89ee5b54844b06fdf9ed97e0e2f --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/util/HexFormatter.java @@ -0,0 +1,268 @@ +//****************************************************************** +// Released under the DevelopMentor OpenSource Software License. +// Please consult the LICENSE.jawin file in the project root directory, +// or at http://www.develop.com for details before using this +// software. +//****************************************************************** + +// From the JAWIN source distribution. +package isi.pasco2.util; + +/** + + * Helper class for doing hex dumps of arrays to String. Useful for + + * debugging, esp. on IDEs that are not hex-friendly. + + */ + +public class HexFormatter { + + public static String convertBytesToString(byte[] bytes) { + + return convertBytesToString(bytes, 16, 0, true); + + } + + public static String convertBytesToString( + byte[] bytes, + int lineLength, + int level, + boolean showChars) { + + if (bytes == null) { + + return "(null array)"; + + } + + return convertBytesToString( + bytes, + 0, + bytes.length, + lineLength, + level, + showChars); + + } + + public static String convertBytesToString( + byte[] bytes, + int startOffset, + int endOffset, + int lineLength, + int level, + boolean showChars) { + + if (bytes == null) { + + return "(null array)"; + + } + + int loop = 0; + + //each byte creates 3-4 chars in the string, so the *5 makes a + + //buffer that is large enough + + StringBuffer strb = new StringBuffer(bytes.length * 5); + + int boundary = (startOffset + lineLength - 1) % lineLength; + + int charLoop = 0; + + for (charLoop = loop = startOffset; loop < endOffset; loop++) { + if ((loop % lineLength) == 0) { + for (int j = 0; j < level + 1; j++) { + strb.append("\t"); + } + } + + strb.append(getHexString(bytes[loop])); + + if ((loop % lineLength) == boundary) { + + if (showChars) { + + strb.append(' '); + + while (charLoop <= loop) { + + strb.append(printChars[bytes[charLoop] & 0x00ff]); + + charLoop++; + + } + + } + + strb.append("\r\n"); + + } + + } + + // Added this code to print chars of last line. + + if (showChars && (charLoop < loop)) { + + for (int gap = loop % lineLength; gap < lineLength; ++gap) { + + strb.append(" "); + + } + + strb.append(' '); + + while (charLoop < loop) { + + strb.append(printChars[bytes[charLoop] & 0x00ff]); + + charLoop++; + + } + + } + + return strb.toString(); + + } + + public static String convertBytesToProxyTypeString( + byte[] bytes, + int startOffset, + int endOffset, + int lineLength, + boolean showChars) { + + if (bytes == null) { + return "(null array)"; + } + + int loop = 0; + + //each byte creates 3-4 chars in the string, so the *5 makes a + + //buffer that is large enough + + StringBuffer strb = new StringBuffer(bytes.length * 5); + + int boundary = (startOffset + lineLength - 1) % lineLength; + + int charLoop = 0; + + for (charLoop = loop = startOffset; loop < endOffset; loop++) { + + if (loop == 2) { + strb.append("-"); + } + strb.append(getHexProxyTypeString(bytes[loop])); + + /*if ((loop % lineLength) == boundary) + + { + + if (showChars) + + { + + strb.append(' '); + + while (charLoop <= loop) + + { + + strb.append(printChars[bytes[charLoop] & 0x00ff]); + + charLoop++; + + } + + } + + strb.append("\r\n"); + + }*/ + + } + + // Added this code to print chars of last line. + + /*if ( showChars && ( charLoop < loop ) ) { + + for ( int gap = loop%lineLength; gap < lineLength; ++gap ) { + + strb.append(" "); + + } + + strb.append(' '); + + while ( charLoop < loop ) { + + strb.append( printChars[bytes[charLoop] & 0x00ff] ); + + charLoop++; + + } + + }*/ + + return strb.toString(); + + } + + public final static char[] hexchars = new char[16]; + + public final static char[] printChars = new char[256]; + + static { + + for (char n = 0; n < 10; n++) + hexchars[n] = (char) ('0' + n); + + for (char n = 10; n < 16; n++) + hexchars[n] = (char) ('A' - 10 + n); + + for (char n = 0; n < 32; n++) + printChars[n] = '.'; + + for (char n = 32; n < 256; n++) + printChars[n] = (char) n; + + //for (char n=128; n<256; n++) + + // printChars[n] = '.'; + + } + + public static char[] getHexString(byte b) { + + char[] result = new char[3]; + + result[0] = hexchars[(b & 0x00f0) >> 4]; + + result[1] = hexchars[b & 0x000f]; + + result[2] = ' '; + + return result; + + } + + public static char[] getHexProxyTypeString(byte b) { + + char[] result = new char[2]; + + result[0] = hexchars[(b & 0x00f0) >> 4]; + + result[1] = hexchars[b & 0x000f]; + + // result[2] = ' '; + + return result; + + } + +} diff --git a/thirdparty/pasco2/src/isi/pasco2/util/StructConverter.java b/thirdparty/pasco2/src/isi/pasco2/util/StructConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..ddc2a14d319ade399e41f7ddb87ad7ff3e6e342e --- /dev/null +++ b/thirdparty/pasco2/src/isi/pasco2/util/StructConverter.java @@ -0,0 +1,280 @@ +package isi.pasco2.util; + +//****************************************************************** +//Released under the DevelopMentor OpenSource Software License. +//Please consult the LICENSE.jawin file in the project root directory, +//or at http://www.develop.com for details before using this +//software. +//****************************************************************** +//From the JAWIN source distribution. + +public class StructConverter { + /* + + public static INative structToMem(IStruct s) + + throws COMException + + { + + byte[] bytes = s.instToBytes(); + + System.out.println(HexFormatter.convertBytesToString(bytes, 16, true)); + + if (bytes == null) { + + throw new Error("reflective marshalling not implemented yet"); + + } + + MemPtr mp = new MemPtr(bytes); + + return mp; + + } + + */ + static public long parseLong(String val) { + int length = val.length(); + if (length > 16) { + throw new NumberFormatException("too many digits"); + } + int shift = 0; + long res = 0; + for (int i = length - 1; i >= 0; i--) { + res = res + ((long) Character.digit(val.charAt(i), 16) << shift); + shift += 4; + } + return res; + } + static public int parseInt(String val) { + int length = val.length(); + if (length > 8) { + throw new NumberFormatException("too many digits"); + } + int shift = 0; + int res = 0; + for (int i = length - 1; i >= 0; i--) { + res = res + (Character.digit(val.charAt(i), 16) << shift); + shift += 4; + } + return res; + } + static public short parseShort(String val) { + int length = val.length(); + if (length > 4) { + throw new NumberFormatException("too many digits"); + } + int shift = 0; + int res = 0; + for (int i = length - 1; i >= 0; i--) { + res = res + (Character.digit(val.charAt(i), 16) << shift); + shift += 4; + } + return (short) res; + } + static public int longIntoBEBytes(long data, byte[] bytes, int start) { + bytes[start++] = (byte) (data >>> 56); + bytes[start++] = (byte) (data >>> 48); + bytes[start++] = (byte) (data >>> 40); + bytes[start++] = (byte) (data >>> 32); + bytes[start++] = (byte) (data >>> 24); + bytes[start++] = (byte) (data >>> 16); + bytes[start++] = (byte) (data >>> 8); + bytes[start++] = (byte) (data); + return start; + } + static public long bytesIntoLong(byte[] bytes, int offset) { + int nLo = bytesIntoInt(bytes, offset); + int nHi = bytesIntoInt(bytes, offset + 4); + return ((long) (nHi) << 32) + (nLo & 0xFFFFFFFFL); + } + static public double bytesIntoDouble(byte[] bytes, int offset) { + double d = Double.longBitsToDouble(bytesIntoLong(bytes, offset)); + return d; + } + static public boolean bytesIntoBoolean(byte[] bytes, int offset) { + return bytes[offset] != 0; + } + static public int bytesIntoInt(byte[] bytes, int offset) { + int l = + (bytes[offset] & 0xff) + | ((bytes[offset + 1] & 0xff) << 8) + | ((bytes[offset + 2] & 0xff) << 16) + | ((bytes[offset + 3] & 0xff) << 24); + return l; + } + + static public long bytesIntoUInt(byte[] bytes, int offset) { + long l = ( ((long)bytes[offset] & 0xff) + | (((long)bytes[offset + 1] & 0xff) << 8) + | (((long)bytes[offset + 2] & 0xff) << 16) + | (((long)bytes[offset + 3] & 0xff) << 24) ) ; + return l; + } + static public int BEBytesIntoInt(byte[] bytes, int offset) { + int l = + (bytes[offset + 3] & 0xff) + | ((bytes[offset + 2] & 0xff) << 8) + | ((bytes[offset + 1] & 0xff) << 16) + | ((bytes[offset + 0] & 0xff) << 24); + return l; + } + static public short bytesIntoShort(byte[] bytes, int offset) { + int l = (bytes[offset] & 0xff) | ((bytes[offset + 1] & 0xff) << 8); + return (short) l; + } + static public int longIntoBytes(long data, byte[] bytes, int start) { + bytes[start++] = (byte) (data); + bytes[start++] = (byte) (data >>> 8); + bytes[start++] = (byte) (data >>> 16); + bytes[start++] = (byte) (data >>> 24); + bytes[start++] = (byte) (data >>> 32); + bytes[start++] = (byte) (data >>> 40); + bytes[start++] = (byte) (data >>> 48); + bytes[start++] = (byte) (data >>> 56); + return start; + } + static public int intIntoBytes(int data, byte[] bytes, int start) { + bytes[start++] = (byte) (data); + bytes[start++] = (byte) (data >>> 8); + bytes[start++] = (byte) (data >>> 16); + bytes[start++] = (byte) (data >>> 24); + return start; + } + static public int shortIntoBytes(short data, byte[] bytes, int start) { + bytes[start++] = (byte) (data); + bytes[start++] = (byte) (data >>> 8); + return start; + } + static public int byteArrayIntoBytes(byte[] src, byte[] dest, int start) { + System.arraycopy(src, 0, dest, start, src.length); + return start + src.length; + } + + + static public int stringIntoNullTerminatedASCIIBytes( + String str, + byte[] bytes, + int start) { + int index = stringIntoASCIIBytes(str, bytes, start); + bytes[index++] = 0; + return index; + } + + static public int stringIntoASCIIBytes( + String str, + byte[] bytes, + int start) { + if (str == null) { + return -1; + } + for (int n = 0; n < str.length(); n++) { + bytes[start++] = (byte) str.charAt(n); + } + return start; + } + + /* + * Does not null terminate the bytes + */ + static public int stringIntoUnicodeBytes( + String data, + byte[] bytes, + int start) { + for (int i = 0; i < data.length(); i++) { + int v = data.charAt(i); + bytes[start++] = (byte) ((v >>> 0) & 0xFF); + bytes[start++] = (byte) ((v >>> 8) & 0xFF); + } + return start; + } + static public int stringIntoNullTermintedUnicodeBytes( + String data, + byte[] bytes, + int start) { + start = stringIntoUnicodeBytes(data, bytes, start); + bytes[start++] = (byte) 0; + bytes[start++] = (byte) 0; + return start; + } + /* + * Does not null terminate the bytes + */ + static public String unicodeBytesIntoString( + byte[] bytes, + int offset, + int length) { + StringBuffer res = new StringBuffer(); + for (int i = 0; i < length; i++) { + int v = + ((bytes[offset + i * 2]) | (bytes[offset + i * 2 + 1] << 8)); + char c = (char) v; + res.append(c); + } + return res.toString(); + } + /* + * Does deal with null terminated bytes + */ + static public String nullTerminatedUnicodeBytesIntoString( + byte[] bytes, + int offset, + int length) { + StringBuffer res = new StringBuffer(); + for (int i = 0; i < length; i++) { + int v = + ((bytes[offset + i * 2]) | (bytes[offset + i * 2 + 1] << 8)); + if (v == 0) { + break; + } else { + char c = (char) v; + res.append(c); + } + } + return res.toString(); + } + static public String nullTerminatedAsciiBytesIntoString( + byte[] bytes, + int offset, + int length) { + StringBuffer res = new StringBuffer(); + for (int i = 0; i < length; i++) { + int v = (bytes[offset + i]); + if (v == 0) + break; + char c = (char) v; + res.append(c); + } + return res.toString(); + } + static public String asciiBytesIntoString( + byte[] bytes, + int offset, + int length) { + StringBuffer res = new StringBuffer(); + for (int i = 0; i < length; i++) { + int v = (bytes[offset + i]); + char c = (char) v; + res.append(c); + } + return res.toString(); + } + + public static short lowword(int word) { + return (short) (word & 0x0000FFFF); + } + + public static short highword(int word) { + return (short) ((word & 0xFFFF0000) >> 16); + } + + public static byte lowbyte(short word) { + return (byte) (word & 0x00FF); + } + + public static byte highbyte(short word) { + return (byte) ((word & 0xFF00) >> 8); + } +} + diff --git a/thirdparty/pasco2/test/isi/pasco2/TestAllocationLayer.java b/thirdparty/pasco2/test/isi/pasco2/TestAllocationLayer.java new file mode 100644 index 0000000000000000000000000000000000000000..e87537724411df8bfe89e0c771fb544fdb4d9e0b --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/TestAllocationLayer.java @@ -0,0 +1,111 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2; + + +import isi.pasco2.handler.CountingCacheHandler; +import isi.pasco2.io.FastReadIndexFile; +import isi.pasco2.io.IndexFile; +import isi.pasco2.parser.IEHistoryFileParser; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import com.sun.org.apache.xalan.internal.xsltc.dom.BitArray; + +public class TestAllocationLayer extends TestCase { + + public static TestSuite suite() { + return new TestSuite(TestAllocationLayer.class); + } + + + + public void testHistoryFile() { + try { + String f = "D:\\Documents and Settings\\bschatz\\Local Settings\\History\\History.IE5\\index.dat"; + IndexFile fr = new FastReadIndexFile(f, "r"); + CountingCacheHandler handler = new CountingCacheHandler(); + IEHistoryFileParser parser = new IEHistoryFileParser(f, fr); + + int allocatorBitMapOffset = 0x250; + int bitMapIndex = 0; + int storageStart = 0x4000; + parser.primaryHashOffset = storageStart; + int address = 0; + while (address != storageStart) { + fr.seek(allocatorBitMapOffset + bitMapIndex*4); + + int[] bitmap = {fr.readLittleEndianInt()}; + BitArray bits = new BitArray(32, bitmap); + + for (int i = 0 ; i < 32 ; i++ ){ + address = (bitMapIndex*32+i) * 0x80 + storageStart; + fr.seek(address); + int dword = fr.readLittleEndianInt(); + + System.out.println((bitMapIndex*32+i) + " " + Integer.toHexString(dword) + " " + Integer.toHexString(address)); + assertTrue(bits.getBit(i) == parser.getAllocator().isRecordAllocated(address)); + + } + bitMapIndex += 1; + } + } catch (Exception e) { + } + } + + public void testCacheFile() { + try { + String f = "D:\\mysrc\\squidbro\\IFIP2006\\anon\\source\\minnow.willk.content.index.dat"; + IndexFile fr = new FastReadIndexFile(f, "r"); + CountingCacheHandler handler = new CountingCacheHandler(); + IEHistoryFileParser parser = new IEHistoryFileParser(f, fr); + + int allocatorBitMapOffset = 0x250; + int bitMapIndex = 0; + int storageStart = 0x5000; + parser.primaryHashOffset = storageStart; + int address = 0; + while (address != storageStart) { + fr.seek(allocatorBitMapOffset + bitMapIndex*4); + + int[] bitmap = {fr.readLittleEndianInt()}; + BitArray bits = new BitArray(32, bitmap); + + for (int i = 0 ; i < 32 ; i++ ){ + address = (bitMapIndex*32+i) * 0x80 + storageStart; + fr.seek(address); + int dword = fr.readLittleEndianInt(); + + System.out.println((bitMapIndex*32+i) + " " + Integer.toHexString(dword) + " " + Integer.toHexString(address)); + assertTrue(bits.getBit(i) == parser.getAllocator().isRecordAllocated(address)); + + } + bitMapIndex += 1; + } + } catch (Exception e) { + } + } + + +} diff --git a/thirdparty/pasco2/test/isi/pasco2/TestDOSTime.java b/thirdparty/pasco2/test/isi/pasco2/TestDOSTime.java new file mode 100644 index 0000000000000000000000000000000000000000..d187e25d8ddb62f5efb15f82fdb09e7f135f2645 --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/TestDOSTime.java @@ -0,0 +1,55 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2; + + +import isi.pasco2.parser.time.DOSTime; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class TestDOSTime extends TestCase { + + public static TestSuite suite() { + return new TestSuite(TestDOSTime.class); + } + + public void testHexLittleEndian() { + String hex = "F788F41E"; + DOSTime ft = DOSTime.parseLittleEndianHex(hex); + //Sat, 30 September 2000 14:46:43 GMT + assertEquals("1995-07-20T17:07:46.000Z", ft.toString()); + + //Wed, 26 April 2000 22:58:55 GMT + assertEquals("2000-01-31T15:21:44.000Z", DOSTime.parseLittleEndianHex("B67A3F28").toString()); + //Sat, 30 March 2002 05:15:11 GMT + assertEquals("2001-10-12T22:10:02.000Z", DOSTime.parseLittleEndianHex("41B14C2B").toString()); + } + + public void testCorrectLocal() { + + DOSTime ft = new DOSTime(13404, 1075); + //Sat, 30 September 2000 14:46:43 GMT + assertEquals("2006-02-28T00:33:38.000Z", ft.toString()); + } +} diff --git a/thirdparty/pasco2/test/isi/pasco2/TestFileTime.java b/thirdparty/pasco2/test/isi/pasco2/TestFileTime.java new file mode 100644 index 0000000000000000000000000000000000000000..7ab910ab0dfabfdb7e1d3bded1ef435a6ec3c74c --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/TestFileTime.java @@ -0,0 +1,124 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2; + + +import isi.pasco2.parser.time.FileTime; +import isi.pasco2.util.StructConverter; + +import java.util.Date; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class TestFileTime extends TestCase { + + public static TestSuite suite() { + return new TestSuite(TestFileTime.class); + } + + public void testFileTime() { + long low = -543274336; + long high = 29744990; + FileTime ft = new FileTime(low, high); + long millis = ft.getTimeAsMillis(); + //assertEquals(1130902272657L, millis); + + Date d = ft.asDate(); + assertEquals("Wed Nov 02 13:31:12 EST 2005", d.toString()); + assertEquals("2005-11-02T03:31:12.657Z", ft.toString()); + } + + public void testBitStuff() { + String hex = "40B3B13F"; + byte[] bytes = new byte[4]; + for (int i=0 ; i < 4 ; i++) { + bytes[i] = (byte)Integer.parseInt(hex.substring(i*2, i*2+2), 16); + } + + long res = StructConverter.bytesIntoInt(bytes,0); + assertEquals(1068610368,res); + long low = Long.parseLong(hex.substring(0,8) , 16); + low = ((low & 0xFF) << 24) | ((low & 0x0FF00) << 8) | ((low & 0xFF0000) >> 8) | ((low & 0xFF000000)>> 24); + assertEquals(1068610368,low); + } + + public void testHexLittleEndian() { + String hex = "40B3B13FED2AC001"; + FileTime ft = FileTime.parseLittleEndianHex(hex); + //Sat, 30 September 2000 14:46:43 GMT + assertEquals("2000-09-30T14:46:43.060Z", ft.toString()); + + //Wed, 26 April 2000 22:58:55 GMT + assertEquals("2000-04-26T22:58:55.899Z", FileTime.parseLittleEndianHex("39B1C8FFD2AFBF01").toString()); + //Sat, 30 March 2002 05:15:11 GMT + assertEquals("2002-03-30T05:15:11.620Z", FileTime.parseLittleEndianHex("69D8F2DDA9D7C101").toString()); + //Mon, 17 October 2005 02:59:22 UTC + assertEquals("2005-10-17T02:59:22.147Z", FileTime.parseLittleEndianHex("308F41C6C6D2C501").toString()); + } + + public void testHexBigEndian() { + String hex = "01C1D7A9DDF2D869"; + FileTime ft = FileTime.parseBigEndianHex(hex); + //Sat, 30 March 2002 05:15:11 GMT + assertEquals("2002-03-30T05:15:11.620Z", ft.toString()); + + // Sun, 10 March 2002 06:07:32 GMT + assertEquals("2002-03-10T06:07:32.813Z", FileTime.parseBigEndianHex("01C1C7F9DDFBD86F").toString()); + // Tue, 20 January 2004 04:58:58 GMT + assertEquals("2004-01-20T04:58:58.985Z", FileTime.parseBigEndianHex("01C3DF121D432432").toString()); + + } + + public void testPassingInts() { + int[] intsLow = { 0x30, 0x8F, 0x41, 0xC6 }; + byte[] bytesLow = new byte[4]; + + for (int i=0 ; i < 4 ; i++) { + bytesLow[i] = (byte) (intsLow[i] & 0xFF); + } + long low = StructConverter.bytesIntoUInt(bytesLow, 0); + + long lowA = Long.parseLong("308F41C6", 16); + lowA = ((lowA & 0xFF) << 24) | ((lowA & 0x0FF00) << 8) | ((lowA & 0xFF0000) >> 8) | ((lowA & 0xFF000000)>> 24); + + assertEquals(lowA, low); + + + int[] intsHigh = { 0xC6, 0xD2, 0xC5, 0x01 }; + byte[] bytesHigh = new byte[4]; + + for (int i=0 ; i < 4 ; i++) { + bytesHigh[i] = (byte) (intsHigh[i] & 0xFF); + } + long high = StructConverter.bytesIntoUInt(bytesHigh, 0); + + FileTime ft = new FileTime(low, high); + assertEquals("2005-10-17T02:59:22.147Z", ft.toString()); + + + + } + +} diff --git a/thirdparty/pasco2/test/isi/pasco2/TestPackage.java b/thirdparty/pasco2/test/isi/pasco2/TestPackage.java new file mode 100644 index 0000000000000000000000000000000000000000..383cbb682eaa166fe3584027a89b7f6837ba74db --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/TestPackage.java @@ -0,0 +1,51 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class TestPackage extends TestSuite { + + static public Test suite() { + return new TestPackage(); + } + + /** Creates new TestPackage */ + private TestPackage() { + super("fore"); + addTest("FileTime", TestFileTime.suite()); + addTest("DOSTime", TestDOSTime.suite()); + addTest("Allocation", TestAllocationLayer.suite()); + addTest("Record", TestRecordLayer.suite()); + addTest("Supporting byte manipulation functions", TestReadFunctions.suite()); + addTest("Compaison of results with the Win32 API", TestPlatform.suite()); + } + + private void addTest(String name, TestSuite tc) { + tc.setName(name); + addTest(tc); + } + +} \ No newline at end of file diff --git a/thirdparty/pasco2/test/isi/pasco2/TestPlatform.java b/thirdparty/pasco2/test/isi/pasco2/TestPlatform.java new file mode 100644 index 0000000000000000000000000000000000000000..f4bc2cbc61457647d60f920a3b972201192089c0 --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/TestPlatform.java @@ -0,0 +1,238 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2; + +import isi.pasco2.parser.time.FileTime; +import isi.pasco2.platform.FILETIME; +import isi.pasco2.platform.SYSTEMTIME; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import ctypes.java.CDLL; +import ctypes.java.CFunction; +import ctypes.java.CInt; + +public class TestPlatform extends TestCase { + + public static TestSuite suite() { + return new TestSuite(TestPlatform.class); + } + + public void testSystemTimeAPIs() { + try { + CDLL dll = CDLL.LoadLibrary("kernel32.dll"); + CFunction getSystemTimeAsFileTime = dll + .loadFunction("GetSystemTimeAsFileTime"); + + FILETIME ft = new FILETIME(); + Object[] ary = { ft }; + Object o = getSystemTimeAsFileTime.call(null, ary, + CFunction.FUNCFLAG_STDCALL); + long lowValue = ft.dwLowDateTime.getValue(); + long highValue = ft.dwHighDateTime.getValue(); + System.out.println(lowValue); + System.out.println(highValue); + assertTrue(highValue >= 29767328); + /* + * BOOL FileTimeToSystemTime( const FILETIME* lpFileTime, LPSYSTEMTIME + * lpSystemTime ); + */ + + CFunction fileTimeToSystemTime = dll.loadFunction("FileTimeToSystemTime"); + SYSTEMTIME st = new SYSTEMTIME(); + Object[] ary1 = { ft, st }; + o = fileTimeToSystemTime.call(CInt.class, ary1, + CFunction.FUNCFLAG_STDCALL); + int year = st.wYear.getValue(); + assertTrue(year >= 2006); + + } catch (Exception e) { + fail(); + } + } + + public void testComparingSystemTimesWithOurAlgorithm2() { + try { + CDLL dll = CDLL.LoadLibrary("kernel32.dll"); + CFunction getSystemTimeAsFileTime = dll + .loadFunction("GetSystemTimeAsFileTime"); + + int lowValue = 926944912; + int highValue = 29767328; + + FILETIME ft = new FILETIME(); + ft.dwLowDateTime.setValue(lowValue); + ft.dwHighDateTime.setValue(highValue); + + CFunction fileTimeToSystemTime = dll.loadFunction("FileTimeToSystemTime"); + SYSTEMTIME st = new SYSTEMTIME(); + Object[] ary1 = { ft, st }; + + Object o = fileTimeToSystemTime.call(CInt.class, ary1, + CFunction.FUNCFLAG_STDCALL); + assertEquals(2006, st.wYear.getValue()); + assertEquals(2, st.wMonth.getValue()); + assertEquals(21, st.wDay.getValue()); + assertEquals(4, st.wHour.getValue()); + assertEquals(35, st.wMinute.getValue()); + assertEquals(17, st.wSecond.getValue()); + assertEquals(625, st.wMilliseconds.getValue()); + + FileTime nonSystemFileTime = new FileTime(lowValue, highValue); + assertEquals("2006-02-21T04:35:17.625Z", nonSystemFileTime.toXSDString()); + + } catch (Exception e) { + fail(); + } + } + + public void testComparingSystemTimesWithOurAlgorithm() { + try { + CDLL dll = CDLL.LoadLibrary("kernel32.dll"); + CFunction getSystemTimeAsFileTime = dll + .loadFunction("GetSystemTimeAsFileTime"); + + String hex = "40B3B13FED2AC001"; + FileTime f = FileTime.parseLittleEndianHex(hex); + + FILETIME ft = new FILETIME(); + ft.dwLowDateTime.setValue((int) f.getLow()); + ft.dwHighDateTime.setValue((int) f.getHigh()); + + CFunction fileTimeToSystemTime = dll.loadFunction("FileTimeToSystemTime"); + SYSTEMTIME st = new SYSTEMTIME(); + Object[] ary1 = { ft, st }; + + //Sat, 30 September 2000 14:46:43 + Object o = fileTimeToSystemTime.call(CInt.class, ary1, + CFunction.FUNCFLAG_STDCALL); + assertEquals(2000, st.wYear.getValue()); + assertEquals(9, st.wMonth.getValue()); + assertEquals(30, st.wDay.getValue()); + assertEquals(14, st.wHour.getValue()); + assertEquals(46, st.wMinute.getValue()); + assertEquals(43, st.wSecond.getValue()); + assertEquals(60, st.wMilliseconds.getValue()); + + + } catch (Exception e) { + fail(); + } + } + + public void testZeroFiletime() { + try { + CDLL dll = CDLL.LoadLibrary("kernel32.dll"); + + FILETIME ft = new FILETIME(); + ft.dwLowDateTime.setValue((int) 0); + ft.dwHighDateTime.setValue((int) 0); + + CFunction fileTimeToSystemTime = dll.loadFunction("FileTimeToSystemTime"); + CFunction getFileTimeAsSystemTime = dll.loadFunction("SystemTimeToFileTime"); + + SYSTEMTIME st = new SYSTEMTIME(); + Object[] ary1 = { ft, st }; + + //Sat, 30 September 2000 14:46:43 + Object o = fileTimeToSystemTime.call(CInt.class, ary1, + CFunction.FUNCFLAG_STDCALL); + assertEquals(1601, st.wYear.getValue()); + assertEquals(1, st.wMonth.getValue()); + assertEquals(1, st.wDay.getValue()); + assertEquals(0, st.wHour.getValue()); + assertEquals(0, st.wMinute.getValue()); + assertEquals(0, st.wSecond.getValue()); + assertEquals(0, st.wMilliseconds.getValue()); + + FILETIME zeroFileTime = new FILETIME(); + Object[] a = { st, zeroFileTime }; + Object o1 = getFileTimeAsSystemTime.call(CInt.class, ary1, + CFunction.FUNCFLAG_STDCALL); + + assertEquals(0, zeroFileTime.dwHighDateTime.getValue()); + assertEquals(0, zeroFileTime.dwLowDateTime.getValue()); + + } catch (Exception e) { + fail(); + } + } + + /** + * This test validates the value of the constant called skewFILETIME2timetEpochs + * used as the difference in 100ns ticks between the UNIX and FILETIME epochs. + * + */ + public void testSkewBetweenUNIXEpochAndWindowsEpoch() { + try { + CDLL dll = CDLL.LoadLibrary("kernel32.dll"); + + CFunction systemTimeToFileTime = dll + .loadFunction("SystemTimeToFileTime"); + + SYSTEMTIME zeroTime = new SYSTEMTIME(); + zeroTime.wDay.setValue((short)1); + zeroTime.wMonth.setValue((short)1); + zeroTime.wYear.setValue((short)1601); + zeroTime.wHour.setValue((short)0); + zeroTime.wMinute.setValue((short)0); + zeroTime.wSecond.setValue((short)0); + zeroTime.wMilliseconds.setValue((short)0); + + SYSTEMTIME UNIXepochTime = new SYSTEMTIME(); + UNIXepochTime.wDay.setValue((short)1); + UNIXepochTime.wMonth.setValue((short)1); + UNIXepochTime.wYear.setValue((short)1970); + UNIXepochTime.wHour.setValue((short)0); + UNIXepochTime.wMinute.setValue((short)0); + UNIXepochTime.wSecond.setValue((short)0); + UNIXepochTime.wMilliseconds.setValue((short)0); + + FILETIME zeroFileTime = new FILETIME(); + FILETIME UNIXepochFileTime = new FILETIME(); + + Object[] ary1 = { zeroTime, zeroFileTime }; + CInt o = (CInt) systemTimeToFileTime.call(CInt.class, ary1, + CFunction.FUNCFLAG_STDCALL); + assertTrue(o.getValue() != 0); + + Object[] ary2 = { UNIXepochTime, UNIXepochFileTime }; + CInt o1 = (CInt) systemTimeToFileTime.call(CInt.class, ary2, + CFunction.FUNCFLAG_STDCALL); + assertTrue(o.getValue() != 0); + + long zeroCount = (zeroFileTime.dwHighDateTime.getValue() << 32) + (zeroFileTime.dwLowDateTime.getValue()); + long hi = U32Jint2Jlong(UNIXepochFileTime.dwHighDateTime.getValue()); + long lo = U32Jint2Jlong(UNIXepochFileTime.dwLowDateTime.getValue()); + long UNIXepochCount = ( hi << 32) + (lo); + assertEquals(0, zeroCount); + assertEquals(0x19db1ded53e8000L, UNIXepochCount - zeroCount); + + } catch (Exception e) { + fail(); + } + } + public static final long U32Jint2Jlong(int i) { + return (((long)i) & 0xffff0000L) | i & 0x00ffff; + } +} diff --git a/thirdparty/pasco2/test/isi/pasco2/TestReadFunctions.java b/thirdparty/pasco2/test/isi/pasco2/TestReadFunctions.java new file mode 100644 index 0000000000000000000000000000000000000000..750216b5a4c62b5a73a0cdccbb8d5a7ca9534efe --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/TestReadFunctions.java @@ -0,0 +1,46 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2; + +import isi.pasco2.util.StructConverter; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class TestReadFunctions extends TestCase { + public static TestSuite suite() { + return new TestSuite(TestReadFunctions.class); + } + + public void testVersionReader() { + try { + byte[] fourbytes = { 0, 0, 40, 0 }; + assertEquals(2621440, StructConverter.bytesIntoInt(fourbytes, 0), 0); + + byte[] nextfourbytes = { 0, -112, 1, 0 }; + assertEquals(102400, StructConverter.bytesIntoInt(nextfourbytes, 0)); + } catch (Exception ex) { + fail(); + } + } +} diff --git a/thirdparty/pasco2/test/isi/pasco2/TestRecordLayer.java b/thirdparty/pasco2/test/isi/pasco2/TestRecordLayer.java new file mode 100644 index 0000000000000000000000000000000000000000..1e2400714418be788d0386c36c5ff1179cda26a9 --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/TestRecordLayer.java @@ -0,0 +1,115 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2; + +import isi.pasco2.io.FastReadIndexFile; +import isi.pasco2.io.IndexFile; +import isi.pasco2.parser.IECacheFileParser; +import isi.pasco2.parser.IEHistoryFileParser; +import isi.pasco2.parser.IEIndexFileParser; +import isi.pasco2.parser.ValidRecordIterator; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class TestRecordLayer extends TestCase { + + public static TestSuite suite() { + return new TestSuite(TestRecordLayer.class); + } + + public void testEmptyCacheFile() { + try { + String f = "D:\\mysrc\\pasco2\\src\\test\\isrc\\pasco2\\empty.cache.index.dat"; + IndexFile fr = new FastReadIndexFile(f, "r"); + IEIndexFileParser parser = new IECacheFileParser(f, fr); + parser.parseFile(); + + ValidRecordIterator it = parser.getValidRecords(); + int count = 0; + while (it.hasNext()) { + count += 1; + it.next(); + } + assertEquals(00, count); + } catch (Exception e) { + fail(); + } + } + + public void testInitialCacheFile() { + try { + String f = "D:\\mysrc\\pasco2\\src\\test\\isrc\\pasco2\\first.cache.index.dat"; + IndexFile fr = new FastReadIndexFile(f, "r"); + IEIndexFileParser parser = new IECacheFileParser(f, fr); + + ValidRecordIterator it = parser.getValidRecords(); + int count = 0; + while (it.hasNext()) { + count += 1; + it.next(); + } + assertEquals(30, count); + } catch (Exception e) { + fail(); + } + } + + public void testEmptyHistoryFile() { + try { + String f = "D:\\mysrc\\pasco2\\src\\test\\isrc\\pasco2\\empty.history.index.dat"; + IndexFile fr = new FastReadIndexFile(f, "r"); + IEIndexFileParser parser = new IEHistoryFileParser(f, fr); + parser.parseFile(); + + ValidRecordIterator it = parser.getValidRecords(); + int count = 0; + while (it.hasNext()) { + count += 1; + it.next(); + } + assertEquals(00, count); + } catch (Exception e) { + fail(); + } + } + + public void testInitialHistoryFile() { + try { + String f = "D:\\mysrc\\pasco2\\src\\test\\isrc\\pasco2\\first.history.index.dat"; + IndexFile fr = new FastReadIndexFile(f, "r"); + IEIndexFileParser parser = new IEHistoryFileParser(f, fr); + + ValidRecordIterator it = parser.getValidRecords(); + int count = 0; + while (it.hasNext()) { + count += 1; + it.next(); + } + assertEquals(2, count); + } catch (Exception e) { + fail(); + } + } + +} diff --git a/thirdparty/pasco2/test/isi/pasco2/empty.cache.index.dat b/thirdparty/pasco2/test/isi/pasco2/empty.cache.index.dat new file mode 100644 index 0000000000000000000000000000000000000000..407ed3f8d3de06b6dd2c494910a5045e47157866 Binary files /dev/null and b/thirdparty/pasco2/test/isi/pasco2/empty.cache.index.dat differ diff --git a/thirdparty/pasco2/test/isi/pasco2/empty.history.index.dat b/thirdparty/pasco2/test/isi/pasco2/empty.history.index.dat new file mode 100644 index 0000000000000000000000000000000000000000..cebcc9bbed4ce533839a383b15d1bcfbad9deee3 Binary files /dev/null and b/thirdparty/pasco2/test/isi/pasco2/empty.history.index.dat differ diff --git a/thirdparty/pasco2/test/isi/pasco2/first.cache.index.dat b/thirdparty/pasco2/test/isi/pasco2/first.cache.index.dat new file mode 100644 index 0000000000000000000000000000000000000000..8f5d8f0bc735af8006ba98b3c58764361fa50f34 Binary files /dev/null and b/thirdparty/pasco2/test/isi/pasco2/first.cache.index.dat differ diff --git a/thirdparty/pasco2/test/isi/pasco2/first.history.index.dat b/thirdparty/pasco2/test/isi/pasco2/first.history.index.dat new file mode 100644 index 0000000000000000000000000000000000000000..de442adc063a56dcb682c2882de4463e381d9173 Binary files /dev/null and b/thirdparty/pasco2/test/isi/pasco2/first.history.index.dat differ diff --git a/thirdparty/pasco2/test/isi/pasco2/platform/FILETIME.java b/thirdparty/pasco2/test/isi/pasco2/platform/FILETIME.java new file mode 100644 index 0000000000000000000000000000000000000000..d4add486abb50e00b7bede180bc6930b968f1831 --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/platform/FILETIME.java @@ -0,0 +1,33 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.platform; + +import ctypes.java.CInt; +import ctypes.java.CStruct; + +public class FILETIME extends CStruct { + public CInt dwLowDateTime = new CInt(); + public CInt dwHighDateTime = new CInt(); + +} diff --git a/thirdparty/pasco2/test/isi/pasco2/platform/SYSTEMTIME.java b/thirdparty/pasco2/test/isi/pasco2/platform/SYSTEMTIME.java new file mode 100644 index 0000000000000000000000000000000000000000..75222fd81c1eb05bd970a8c82314454bd2af2c83 --- /dev/null +++ b/thirdparty/pasco2/test/isi/pasco2/platform/SYSTEMTIME.java @@ -0,0 +1,50 @@ +/* + * Copyright 2006 Bradley Schatz. All rights reserved. + * + * This file is part of pasco2, the next generation Internet Explorer cache + * and history record parser. + * + * pasco2 is free software; you can redistribute it and/or modify + * 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. + * + * pasco2 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 pasco2; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +package isi.pasco2.platform; + +import ctypes.java.CShort; +import ctypes.java.CStruct; + +/* + * typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; +} SYSTEMTIME, + */ +public class SYSTEMTIME extends CStruct{ + public CShort wYear = new CShort(); + public CShort wMonth = new CShort(); + public CShort wDayOfWeek = new CShort(); + public CShort wDay = new CShort(); + public CShort wHour = new CShort(); + public CShort wMinute = new CShort(); + public CShort wSecond = new CShort(); + public CShort wMilliseconds = new CShort(); +} diff --git a/thirdparty/rr/p2x588.dll b/thirdparty/rr/p2x588.dll new file mode 100644 index 0000000000000000000000000000000000000000..e250d47eedd893bbc79e81411590278b5c5b11f8 Binary files /dev/null and b/thirdparty/rr/p2x588.dll differ diff --git a/thirdparty/rr/plugins/acmru.pl b/thirdparty/rr/plugins/acmru.pl new file mode 100644 index 0000000000000000000000000000000000000000..55efea5f5d04569e23282a7c7e56bf642627e47a --- /dev/null +++ b/thirdparty/rr/plugins/acmru.pl @@ -0,0 +1,72 @@ +#----------------------------------------------------------- +# acmru.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# ACMru values +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package acmru; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's ACMru key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching acmru v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Search Assistant\\ACMru'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ACMru - Search Assistant"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($s->get_name()." [".gmtime($s->get_timestamp())." (UTC)]"); + my @vals = $s->get_list_of_values(); + my %ac_vals; + foreach my $v (@vals) { + $ac_vals{$v->get_name()} = $v->get_data(); + } + foreach my $a (sort {$a <=> $b} keys %ac_vals) { + ::rptMsg("\t".$a." -> ".$ac_vals{$a}); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/adoberdr.pl b/thirdparty/rr/plugins/adoberdr.pl new file mode 100644 index 0000000000000000000000000000000000000000..f46e5ebd674759b86ad375c6e2d6328ccedff071 --- /dev/null +++ b/thirdparty/rr/plugins/adoberdr.pl @@ -0,0 +1,93 @@ +#----------------------------------------------------------- +# adoberdr.pl +# Plugin for Registry Ripper +# Parse Adobe Reader MRU keys +# +# Change history +# 20100218 - added checks for versions 4.0, 5.0, 9.0 +# 20091125 - modified output to make a bit more clear +# +# References +# +# Note: LastWrite times on c subkeys will all be the same, +# as each subkey is modified as when a new entry is added +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package adoberdr; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100218); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets user's Adobe Reader cRecentFiles values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching adoberdr v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + ::rptMsg("Adoberdr v.".$VERSION); +# First, let's find out which version of Adobe Acrobat Reader is installed + my $version; + my $tag = 0; + my @versions = ("4\.0","5\.0","6\.0","7\.0","8\.0","9\.0"); + foreach my $ver (@versions) { + my $key_path = "Software\\Adobe\\Acrobat Reader\\".$ver."\\AVGeneral\\cRecentFiles"; + if (defined($root_key->get_subkey($key_path))) { + $version = $ver; + $tag = 1; + } + } + + if ($tag) { + ::rptMsg("Adobe Acrobat Reader version ".$version." located."); + my $key_path = "Software\\Adobe\\Acrobat Reader\\".$version."\\AVGeneral\\cRecentFiles"; + my $key = $root_key->get_subkey($key_path); + if ($key) { + ::rptMsg($key_path); + ::rptMsg(""); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my %arkeys; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + foreach my $s (@subkeys) { + my $num = $s->get_name(); + my $data = $s->get_value('sDI')->get_data(); + $num =~ s/^c//; + $arkeys{$num}{lastwrite} = $s->get_timestamp(); + $arkeys{$num}{data} = $data; + } + ::rptMsg("Most recent PDF opened: ".gmtime($arkeys{1}{lastwrite})." (UTC)"); + foreach my $k (sort keys %arkeys) { + ::rptMsg(" c".$k." ".$arkeys{$k}{data}); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg("Could not access ".$key_path); + } + } + else { + ::rptMsg("Adobe Acrobat Reader version not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/aim.pl b/thirdparty/rr/plugins/aim.pl new file mode 100644 index 0000000000000000000000000000000000000000..32eeeae713a302a5fa70582ce608fd1d87a4386e --- /dev/null +++ b/thirdparty/rr/plugins/aim.pl @@ -0,0 +1,95 @@ +#----------------------------------------------------------- +# aim +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package aim; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080325); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets info from the AOL Instant Messenger (not AIM) install"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching aim plugin v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = 'Software\\America Online\\AOL Instant Messenger (TM)\\CurrentVersion\\Users'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("AIM"); + ::rptMsg($key_path); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $user = $s->get_name(); + ::rptMsg("User: $user [".gmtime($s->get_timestamp())."]"); + + my $login = "Login"; + my $recent = "recent IM ScreenNames"; + my $recent2 = "recent ScreenNames"; + + my @userkeys = $s->get_list_of_subkeys(); + foreach my $u (@userkeys) { + my $us = $u->get_name(); +# See if we can get the encrypted password + if ($us =~ m/^$login/) { + my $pwd = ""; + eval { + $pwd = $u->get_value("Password1")->get_data(); + }; + ::rptMsg("Pwd: ".$pwd) if ($pwd ne ""); + } +# See if we can get recent folks they've chatted with... + if ($us eq $recent || $us eq $recent2) { + + my @vals = $u->get_list_of_values(); + if (scalar(@vals) > 0) { + ::rptMsg($user."\\".$us); + my %sns; + foreach my $v (@vals) { + $sns{$v->get_name()} = $v->get_data(); + } + + foreach my $i (sort {$a <=> $b} keys %sns) { + ::rptMsg("\t\t".$i." -> ".$sns{$i}); + } + } + else { +# No values + } + } + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/all b/thirdparty/rr/plugins/all new file mode 100644 index 0000000000000000000000000000000000000000..5f28a06eb62a000e03850a2c72aeb3c44517c97f --- /dev/null +++ b/thirdparty/rr/plugins/all @@ -0,0 +1,3 @@ +#------------------------------------- +# All +regtime \ No newline at end of file diff --git a/thirdparty/rr/plugins/appinitdlls.pl b/thirdparty/rr/plugins/appinitdlls.pl new file mode 100644 index 0000000000000000000000000000000000000000..29c75915b153dccd5562a1a2559d16939689945c --- /dev/null +++ b/thirdparty/rr/plugins/appinitdlls.pl @@ -0,0 +1,61 @@ +#----------------------------------------------------------- +# appinitdlls +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package appinitdlls; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of AppInit_DLLs value"; +} +sub getDescr{} +sub getRefs { + my %refs = ("Working with the AppInit_DLLs Reg Value" => + "http://support.microsoft.com/kb/q197571"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching appinitdlls v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = 'Microsoft\\Windows NT\\CurrentVersion\\Windows'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("AppInit_DLLs"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + foreach my $v (@vals) { + my $name = $v->get_name(); + if ($name eq "AppInit_DLLs") { + my $data = $v->get_data(); + $data = "{blank}" if ($data eq ""); + ::rptMsg($name." -> ".$data); + } + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/applets.pl b/thirdparty/rr/plugins/applets.pl new file mode 100644 index 0000000000000000000000000000000000000000..e29fffa083d515c03f1d3f75ed022cdb92de9b1f --- /dev/null +++ b/thirdparty/rr/plugins/applets.pl @@ -0,0 +1,96 @@ +#----------------------------------------------------------- +# applets.pl +# Plugin for Registry Ripper +# Windows\CurrentVersion\Applets Recent File List values +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package applets; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's Applets key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching applets v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Applets'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Applets"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); +# Locate files opened in MS Paint + my $paint_key = 'Paint\\Recent File List'; + my $paint = $key->get_subkey($paint_key); + if (defined $paint) { + ::rptMsg($key_path."\\".$paint_key); + ::rptMsg("LastWrite Time ".gmtime($paint->get_timestamp())." (UTC)"); + + my @vals = $paint->get_list_of_values(); + if (scalar(@vals) > 0) { + my %files; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/File/,$val))[1]; + $files{$tag} = $val.":".$data; + } +# Print sorted content to report file + foreach my $u (sort {$a <=> $b} keys %files) { + my ($val,$data) = split(/:/,$files{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path."\\".$paint_key." has no values."); + } + } + else { + ::rptMsg($key_path."\\".$paint_key." not found."); + } +# Get Last Registry key opened in RegEdit + my $reg_key = "Regedit"; + my $reg = $key->get_subkey($reg_key); + if (defined $reg) { + ::rptMsg(""); + ::rptMsg($key_path."\\".$reg_key); + ::rptMsg("LastWrite Time ".gmtime($reg->get_timestamp())." (UTC)"); + my $lastkey = $reg->get_value("LastKey")->get_data(); + ::rptMsg("RegEdit LastKey value -> ".$lastkey); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/apppaths.pl b/thirdparty/rr/plugins/apppaths.pl new file mode 100644 index 0000000000000000000000000000000000000000..85e00aab25d1cfcbc09e0f032cc10c01efcb397e --- /dev/null +++ b/thirdparty/rr/plugins/apppaths.pl @@ -0,0 +1,83 @@ +#----------------------------------------------------------- +# apppaths +# Gets contents of App Paths subkeys from the Software hive, +# diplaying the EXE name and path; all entries are sorted by +# LastWrite time +# +# References +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package apppaths; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20080404); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets content of App Paths key"; +} +sub getDescr{} +sub getRefs { + my %refs = ("You cannot open Help and Support Center in Windows XP" => + "http://support.microsoft.com/kb/888018", + "Another installation program starts..." => + "http://support.microsoft.com/kb/888470"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching apppaths v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\App Paths"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("App Paths"); + ::rptMsg($key_path); + ::rptMsg(""); + my %apps; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + + my $name = $s->get_name(); + my $lastwrite = $s->get_timestamp(); + my $path; + eval { + $path = $s->get_value("")->get_data(); + }; + push(@{$apps{$lastwrite}},$name." [".$path."]"); + } + + foreach my $t (reverse sort {$a <=> $b} keys %apps) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$apps{$t}}) { + ::rptMsg(" $item"); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/arpcache.pl b/thirdparty/rr/plugins/arpcache.pl new file mode 100644 index 0000000000000000000000000000000000000000..b8ed74f88ffc8f9098112e814f358f4291253cc5 --- /dev/null +++ b/thirdparty/rr/plugins/arpcache.pl @@ -0,0 +1,133 @@ +#----------------------------------------------------------- +# arpcache.pl +# Retrieves CurrentVersion\App Management\ARPCache entries; subkeys appear +# to maintain information about paths to installed applications in the +# SlowInfoCache value(0x10 - FILETIME object, null term. string with path +# starts at 0x1c) +# +# Change history +# 20090413 - Created +# +# References +# No references, but the subkeys appear to hold information about +# installed applications; some SlowInfoCache values appear to contain +# timestamp data (FILETIME object) and/or path information. Posts on +# the Internet indicate the existence of Kazaa beneath the APRCache key, +# as well as possibly an "Outerinfo" subkey indicating that spyware is +# installed. +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package arpcache; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090413); + +sub getConfig{return %config} +sub getShortDescr { + return "Retrieves CurrentVersion\\App Management\\ARPCache entries"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %arpcache; + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching arpcache v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\App Management\\ARPCache'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $lw = $s->get_timestamp(); + my $name = $s->get_name(); + + my $path; + eval { + my $i = $s->get_value("SlowInfoCache")->get_data(); + $path = parsePath($i); + }; + ($@) ? ($name .= "|") : ($name .= "|".$path); + + my $date; + eval { + my $i = $s->get_value("SlowInfoCache")->get_data(); + $date = parseDate($i); + }; + ($@) ? ($name .= "|") : ($name .= "|".$date); + push(@{$arpcache{$lw}},$name); + } + + + foreach my $t (reverse sort {$a <=> $b} keys %arpcache) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$arpcache{$t}}) { + my ($name,$path,$date) = split(/\|/,$item,3); + ::rptMsg(" ".$name); + my $str = $path unless ($path eq ""); + $str .= " [".gmtime($date)."]" unless ($date == 0); + ::rptMsg(" -> ".$str) unless ($str eq ""); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; + +sub parseDate { + my $data = shift; + my ($t1,$t2) = unpack("VV",substr($data,0x10,8)); + return ::getTime($t1,$t2); +} + +sub parsePath { + my $data = shift; + my $ofs = 0x1c; + my $tag = 1; + + my $str = substr($data,$ofs,2); + if (unpack("v",$str) == 0) { + return ""; + } + else { + while($tag) { + $ofs += 2; + my $i = substr($data,$ofs,2); + if (unpack("v",$i) == 0) { + $tag = 0; + } + else { + $str .= $i; + } + } + } + $str =~ s/\00//g; + return $str; +} \ No newline at end of file diff --git a/thirdparty/rr/plugins/assoc.pl b/thirdparty/rr/plugins/assoc.pl new file mode 100644 index 0000000000000000000000000000000000000000..a2587da110b56070af392b79895a3eab16a8a845 --- /dev/null +++ b/thirdparty/rr/plugins/assoc.pl @@ -0,0 +1,87 @@ +#----------------------------------------------------------- +# assoc.pl +# Plugin to extract file association data from the Software hive file +# Can take considerable time to run; recommend running it via rip.exe +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package assoc; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080815); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get list of file ext associations"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching assoc v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Classes"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("assoc"); + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); +# First step will be to get a list of all of the file extensions + my %ext; + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + my $name = $s->get_name(); + next unless ($name =~ m/^\.\w+$/); + my $data; + eval { + $data = $s->get_value("")->get_data(); + }; + if ($@) { +# Error generated, as "(Default)" value was not found + } + else { + $ext{$name} = $data if ($data ne ""); + } + } +# Once a list of all file ext subkeys has been compiled, access the file type +# to determine the command line used to launch files with that extension + foreach my $e (keys %ext) { + my $cmd; + eval { + $cmd = $key->get_subkey($ext{$e}."\\shell\\open\\command")->get_value("")->get_data(); + }; + if ($@) { +# error generated attempting to locate <file type>.\shell\open\command\(Default) value + } + else { + ::rptMsg($e." : ".$cmd); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/auditfail.pl b/thirdparty/rr/plugins/auditfail.pl new file mode 100644 index 0000000000000000000000000000000000000000..019ec15eda4ca159635b2d2bb4257a9c48afeebb --- /dev/null +++ b/thirdparty/rr/plugins/auditfail.pl @@ -0,0 +1,66 @@ +#----------------------------------------------------------- +# auditfail.pl +# +# Ref: +# http://support.microsoft.com/kb/140058 +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package auditfail; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081212); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get CrashOnAuditFail value"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my %val = (0 => "Feature is off; the system will not halt", + 1 => "Feature is on; the system will halt when events cannot be written to the ". + "Security Event Log", + 2 => "Feature is on and has been triggered; only Administrators can log in"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching auditfail v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + + my $lsa_path = "ControlSet00".$current."\\Control\\Lsa"; + my $lsa; + if ($lsa = $root_key->get_subkey($lsa_path)) { + + eval { + my $crash = $lsa->get_value("crashonauditfail")->get_data(); + ::rptMsg("CrashOnAuditFail = ".$crash); + ::rptMsg($val{$crash}); + }; + ::rptMsg($@) if ($@); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; diff --git a/thirdparty/rr/plugins/auditpol.pl b/thirdparty/rr/plugins/auditpol.pl new file mode 100644 index 0000000000000000000000000000000000000000..11ea9a10960d897241113cfc75d5110ec3c32a55 --- /dev/null +++ b/thirdparty/rr/plugins/auditpol.pl @@ -0,0 +1,88 @@ +#----------------------------------------------------------- +# auditpol +# Get the audit policy from the Security hive file +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package auditpol; +use strict; + +my %config = (hive => "Security", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + osmask => 22, + version => 20080327); + +sub getConfig{return %config} +sub getShortDescr { + return "Get audit policy from the Security hive file"; +} +sub getDescr{} +sub getRefs { + my %refs = ("How To Determine Audit Policies from the Registry" => + "http://support.microsoft.com/default.aspx?scid=kb;EN-US;q246120"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %audit = (0 => "N", + 1 => "S", + 2 => "F", + 3 => "S/F"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching auditpol v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Policy\\PolAdtEv"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("auditpol"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $data; + eval { + $data = $key->get_value("")->get_data(); + }; + if ($@) { + ::rptMsg("Error occurred getting data from ".$key_path); + ::rptMsg(" - ".$@); + } + else { +# Check to see if auditing is enabled + my $enabled = unpack("C",substr($data,0,1)); + if ($enabled) { + ::rptMsg("Auditing is enabled."); +# Get audit configuration settings + my @vals = unpack("V*",$data); + ::rptMsg("\tAudit System Events = ".$audit{$vals[1]}); + ::rptMsg("\tAudit Logon Events = ".$audit{$vals[2]}); + ::rptMsg("\tAudit Object Access = ".$audit{$vals[3]}); + ::rptMsg("\tAudit Privilege Use = ".$audit{$vals[4]}); + ::rptMsg("\tAudit Process Tracking = ".$audit{$vals[5]}); + ::rptMsg("\tAudit Policy Change = ".$audit{$vals[6]}); + ::rptMsg("\tAudit Account Management = ".$audit{$vals[7]}); + ::rptMsg("\tAudit Dir Service Access = ".$audit{$vals[8]}); + ::rptMsg("\tAudit Account Logon Events = ".$audit{$vals[9]}); + } + else { + ::rptMsg("**Auditing is NOT enabled."); + } + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/autoendtasks.pl b/thirdparty/rr/plugins/autoendtasks.pl new file mode 100644 index 0000000000000000000000000000000000000000..29b89d20ae37f7d0cac9ed3cd8dbad81a3019dd1 --- /dev/null +++ b/thirdparty/rr/plugins/autoendtasks.pl @@ -0,0 +1,66 @@ +#----------------------------------------------------------- +# autoendtasks.pl +# +# History +# 20081128 - created +# +# Ref: +# http://support.microsoft.com/kb/555619 +# This Registry setting tells XP (and Vista) to automatically +# end non-responsive tasks; value may not exist on Vista. +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package autoendtasks; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081128); + +sub getConfig{return %config} + +sub getShortDescr { + return "Automatically end a non-responsive task"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching autoendtasks v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = 'Control Panel\\Desktop'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { +# ::rptMsg("autoendtasks"); + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $autoend; + eval { + $autoend = $key->get_value("AutoEndTasks")->get_data(); + }; + if ($@) { + ::rptMsg("AutoEndTasks value not found."); + } + else { + ::rptMsg("AutoEndTasks = ".$autoend); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/autorun.pl b/thirdparty/rr/plugins/autorun.pl new file mode 100644 index 0000000000000000000000000000000000000000..50604cf4ddc9f63034d391294e361b0c0e1ba47e --- /dev/null +++ b/thirdparty/rr/plugins/autorun.pl @@ -0,0 +1,74 @@ +#----------------------------------------------------------- +# autorun.pl +# Get autorun settings +# +# Change history +# +# +# References +# http://support.microsoft.com/kb/953252 +# http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit +# /regentry/91525.mspx?mfr=true +# +# copyright 2008-2009 H. Carvey +#----------------------------------------------------------- +package autorun; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081212); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets autorun settings"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching autorun v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { +# ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + eval { + my $nodrive = $key->get_value("NoDriveTypeAutoRun")->get_data(); + my $str = sprintf "%-20s 0x%x","NoDriveTypeAutoRun",$nodrive; + ::rptMsg($str); + }; + ::rptMsg("Error: ".$@) if ($@); + +# http://support.microsoft.com/kb/953252 + eval { + my $honor = $key->get_value("HonorAutorunSetting")->get_data(); + my $str = sprintf "%-20s 0x%x","HonorAutorunSetting",$honor; + ::rptMsg($str); + }; + ::rptMsg("HonorAutorunSetting not found.") if ($@); + ::rptMsg(""); + ::rptMsg("Autorun settings in the HKLM hive take precedence over those in"); + ::rptMsg("the HKCU hive."); + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/bagtest.pl b/thirdparty/rr/plugins/bagtest.pl new file mode 100644 index 0000000000000000000000000000000000000000..cdc5600d5cbef6cc517afec90d6acb14d4ff2603 --- /dev/null +++ b/thirdparty/rr/plugins/bagtest.pl @@ -0,0 +1,170 @@ +#----------------------------------------------------------- +# bagtest.pl +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package bagtest; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090828); + +sub getConfig{return %config} + +sub getShortDescr { + return "Test -- BagMRU"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching bagtest v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\Shell\\BagMRU"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $subtree_iter = $key->get_subtree_iterator; + while (my ($k, $val) = $subtree_iter->get_next) { + if (defined $val) { + next unless ($val->get_name() =~ m/^\d+/); + + my $path; + my $data = $val->get_data(); + my $size = unpack("v",substr($data,0,20)); + my $type = unpack("C",substr($data,2,1)); + my $name = (split(/BagMRU/,$k->get_path()))[1]; + + if ($type == 0x47 || $type == 0x46 || $type == 0x42 || $type == 0x41 || + $type == 0xc3) { + + my $str1 = getStrings1($data); + $path = $str1; + + } + elsif ($type == 0x31 || $type == 0x32) { + my($ascii,$uni) = getStrings2($data); + $path = $uni; + } + elsif ($type == 0x2f) { +# bytes 3-5 of $data contain a drive letter + $path = substr($data,0x03,3); + } + else { +# Nothing + } +# my $str = sprintf "%-30s %-3s %-4s 0x%x",$name."\\".$val->get_name(),$size,length($data),$type; + my $str = sprintf "%-25s ".$path,$name."\\".$val->get_name(); + ::rptMsg($str); + + } + else { + + } + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +#sub getStrings1 { +# my $data = shift; +# my $str; +# my $cursor = 0x05; +# my $tag = 1; +# +# while($tag) { +# my $byte = substr($data,$cursor,1); +# if (unpack("C",$byte) == 0x00) { +# $tag = 0; +# } +# else { +# $str .= $byte; +# $cursor += 1; +# } +# } +# return $str; +#} + +sub getStrings1 { + my $data = shift; + my $d = substr($data,0x05,length($data) - 1); + $d =~ s/\00/-/g; + $d =~ s/[[:cntrl:]]//g; + + my @t = split(/-/,$d); + + my @s; + for my $i (1..scalar(@t) - 1) { + push(@s,$t[$i]) if (length($t[$i]) > 2); + } + + return $t[0]." (".join(',',@s).")"; +} + +sub getStrings2 { +# ASCII short name starts at 0x0E, and is \00 terminated; 0x14 bytes +# after that is the null-term Unicode name + my $data = shift; + my ($ascii,$uni); + my $cursor = 0x0e; + my $tag = 1; + + while($tag) { + my $byte = substr($data,$cursor,1); + if (unpack("C",$byte) == 0x00) { + $tag = 0; + } + else { + $ascii .= $byte; + $cursor += 1; + } + } + + $cursor += 0x14; + + $uni = substr($data,$cursor,length($data) - 1); + $uni =~ s/\00//g; + $uni =~ s/[[:cntrl:]]//g; + return ($ascii,$uni); +} + +1; + + + + + +# Original code to traverse through values and subkeys +# Retain for legacy code purposes +#sub traverse { +# my $key = shift; +# +# foreach my $val ($key->get_list_of_values()) { +# next unless ($val->get_name() =~ m/\d+/); +# +# ::rptMsg($val->get_name()); +# +# } +# +# foreach my $subkey ($key->get_list_of_subkeys()) { +# traverse($subkey); +# } +#} \ No newline at end of file diff --git a/thirdparty/rr/plugins/bagtest2.pl b/thirdparty/rr/plugins/bagtest2.pl new file mode 100644 index 0000000000000000000000000000000000000000..59716d2fd814d96ae24da43da76ce056c5c904df --- /dev/null +++ b/thirdparty/rr/plugins/bagtest2.pl @@ -0,0 +1,161 @@ +#----------------------------------------------------------- +# bagtest2.pl +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package bagtest2; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090828); + +sub getConfig{return %config} + +sub getShortDescr { + return "Test -- BagMRU"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %bagmru; +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching bagtest v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\Shell\\BagMRU"; + my $key; + + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + traverse($key); + + foreach my $i (sort keys %bagmru) { + my $str = sprintf "%-30s ".$bagmru{$i},$i; + ::rptMsg($str); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +sub traverse { + my $key = shift; + my $name = (split(/BagMRU/,$key->get_path()))[1]; + + my @bags; + + foreach my $val ($key->get_list_of_values()) { + next unless ($val->get_name() =~ m/\d+/); + + my $path; + my $data = $val->get_data(); + my $size = unpack("v",substr($data,0,20)); + my $type = unpack("C",substr($data,2,1)); + + + if ($type == 0x47 || $type == 0x46 || $type == 0x42 || $type == 0x41 || + $type == 0xc3) { + + my $str1 = getStrings1($data); + $path = $str1; + + } + elsif ($type == 0x31 || $type == 0x32 || $type == 0xb1) { + my($ascii,$uni) = getStrings2($data); + $path = $uni; + } + elsif ($type == 0x2f) { +# bytes 3-5 of $data contain a drive letter + $path = substr($data,0x03,3); + } + else { +# Nothing + } + $bagmru{$name."\\".$val->get_name()} = $path; + } + + foreach my $subkey ($key->get_list_of_subkeys()) { + traverse($subkey); + } +} + + +sub getStrings1 { + my $data = shift; + my $d = substr($data,0x05,length($data) - 1); + $d =~ s/\00/-/g; + $d =~ s/[[:cntrl:]]//g; + + my @t = split(/-/,$d); + + my @s; + for my $i (1..scalar(@t) - 1) { + push(@s,$t[$i]) if (length($t[$i]) > 2); + } + + return $t[0]." (".join(',',@s).")"; +} + +sub getStrings2 { +# ASCII short name starts at 0x0E, and is \00 terminated; 0x14 bytes +# after that is the null-term Unicode name + my $data = shift; + my ($ascii,$uni); + my $cursor = 0x0e; + my $tag = 1; + + while($tag) { + my $byte = substr($data,$cursor,1); + if (unpack("C",$byte) == 0x00) { + $tag = 0; + } + else { + $ascii .= $byte; + $cursor += 1; + } + } + + $cursor += 0x14; + + if ($ascii eq "RECENT") { + $uni = substr($data,$cursor,length($data) - 1); + $uni =~ s/\00//g; + $uni =~ s/[[:cntrl:]]//g; + } + else { + my $tag = 1; + my $count = 0; + while($tag) { + my $byte = substr($data,$cursor,2); + if ($count > 2 && unpack("v",$byte) == 0x00) { + $tag = 0; + } + else { + $uni .= $byte; + $count++; + $cursor += 2; + } + } + $uni =~ s/\00//g; + $uni =~ s/[[:cntrl:]]//g; + } + return ($ascii,$uni); +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/banner.pl b/thirdparty/rr/plugins/banner.pl new file mode 100644 index 0000000000000000000000000000000000000000..44ae62a274638704e0f79eefb460e27acdb1bca0 --- /dev/null +++ b/thirdparty/rr/plugins/banner.pl @@ -0,0 +1,127 @@ +#----------------------------------------------------------- +# banner +# Get banner information from the SOFTWARE hive file (if any) +# +# Written By: +# Special Agent Brook William Minnick +# Brook_Minnick@doioig.gov +# U.S. Department of the Interior - Office of Inspector General +# Computer Crimes Unit +# 12030 Sunrise Valley Drive Suite 250 +# Reston, VA 20191 +#----------------------------------------------------------- +package banner; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081119); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get HKLM\\SOFTWARE.. Logon Banner Values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching banner v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\policies\\system"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Logon Banner Information"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + +# GET LEGALNOTICECAPTION -- + + my $caption; + eval { + $caption = $key->get_value("Legalnoticecaption")->get_data(); + }; + if ($@) { + ::rptMsg("Legalnoticecaption value not found."); + } + else { + ::rptMsg("Legalnoticecaption value = ".$caption); + } + ::rptMsg(""); + +# GET LEGALNOTICETEXT -- + + my $banner; + eval { + $banner = $key->get_value("Legalnoticetext")->get_data(); + }; + if ($@) { + ::rptMsg("Legalnoticetext value not found."); + } + else { + ::rptMsg("Legalnoticetext value = ".$banner); + } + ::rptMsg(""); + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + +# GET LEGALNOTICECAPTION -- + + my $caption2; + eval { + $caption2 = $key->get_value("Legalnoticecaption")->get_data(); + }; + if ($@) { + ::rptMsg("Legalnoticecaption value not found."); + } + else { + ::rptMsg("Legalnoticecaption value = ".$caption2); + } + ::rptMsg(""); + +# GET LEGALNOTICETEXT -- + + my $banner2; + eval { + $banner2 = $key->get_value("Legalnoticetext")->get_data(); + }; + if ($@) { + ::rptMsg("Legalnoticetext value not found."); + } + else { + ::rptMsg("Legalnoticetext value = ".$banner2); + } + ::rptMsg(""); + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/bho.pl b/thirdparty/rr/plugins/bho.pl new file mode 100644 index 0000000000000000000000000000000000000000..be3b8f6c852de50a02000ff7c30bd460733e812b --- /dev/null +++ b/thirdparty/rr/plugins/bho.pl @@ -0,0 +1,107 @@ +#----------------------------------------------------------- +# bho +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package bho; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + osmask => 22, + version => 20080418); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Browser Helper Objects from Software hive"; +} +sub getDescr{} +sub getRefs { + my %refs = ("Browser Helper Objects" => + "http://msdn2.microsoft.com/en-us/library/bb250436.aspx"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %bhos; + ::logMsg("Launching bho v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Browser Helper Objects"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + next if ($name =~ m/^-/); + my $clsid_path = "Classes\\CLSID\\".$name; + my $clsid; + if ($clsid = $root_key->get_subkey($clsid_path)) { + my $class; + my $mod; + my $lastwrite; + + eval { + $class = $clsid->get_value("")->get_data(); + $bhos{$name}{class} = $class; + }; + if ($@) { + ::logMsg("\tError getting Class name for CLSID\\".$name); + ::logMsg("\t".$@); + } + eval { + $mod = $clsid->get_subkey("InProcServer32")->get_value("")->get_data(); + $bhos{$name}{module} = $mod; + }; + if ($@) { + ::logMsg("\tError getting Module name for CLSID\\".$name); + ::logMsg("\t".$@); + } + eval{ + $lastwrite = $clsid->get_subkey("InProcServer32")->get_timestamp(); + $bhos{$name}{lastwrite} = $lastwrite; + }; + if ($@) { + ::logMsg("\tError getting LastWrite time for CLSID\\".$name); + ::logMsg("\t".$@); + } + + foreach my $b (keys %bhos) { + ::rptMsg($b); + ::rptMsg("\tClass => ".$bhos{$b}{class}); + ::rptMsg("\tModule => ".$bhos{$b}{module}); + ::rptMsg("\tLastWrite => ".gmtime($bhos{$b}{lastwrite})); + ::rptMsg(""); + } + } + else { + ::rptMsg($clsid_path." not found."); + ::rptMsg(""); + ::logMsg($clsid_path." not found."); + } + } + } + else { + ::rptMsg($key_path." has no subkeys. No BHOs installed."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/bitbucket.pl b/thirdparty/rr/plugins/bitbucket.pl new file mode 100644 index 0000000000000000000000000000000000000000..16e61480e968f705cf4650c86682feb27ea14499 --- /dev/null +++ b/thirdparty/rr/plugins/bitbucket.pl @@ -0,0 +1,81 @@ +#----------------------------------------------------------- +# bitbucket +# Get HKLM\..\BitBucket keys\values (if any) +# +# Change history +# 20091020 - Updated; collected additional values +# +# References +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package bitbucket; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080418); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get HKLM\\..\\BitBucket keys\\values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching bitbucket v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + eval { + my $global = $key->get_value("UseGlobalSettings")->get_data(); + ::rptMsg("UseGlobalSettings = ".$global); + }; + + eval { + my $nuke = $key->get_value("NukeOnDelete")->get_data(); + ::rptMsg("NukeOnDelete = ".$nuke); + }; + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($key_path."\\".$s->get_name()); + ::rptMsg("LastWrite Time = ".gmtime($s->get_timestamp())." (UTC)"); + eval { + my $vol = $s->get_value("VolumeSerialNumber")->get_data(); + ::rptMsg("VolumeSerialNumber = 0x".uc(sprintf "%1x",$vol)); + }; + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/bitbucket_user.pl b/thirdparty/rr/plugins/bitbucket_user.pl new file mode 100644 index 0000000000000000000000000000000000000000..e3374fd193a82ac3244f5475e0b3b71a2d5b958a --- /dev/null +++ b/thirdparty/rr/plugins/bitbucket_user.pl @@ -0,0 +1,71 @@ +#----------------------------------------------------------- +# bitbucket_user +# Get HKLM\..\BitBucket keys\values (if any) +# +# Change history +# +# References +# +# NOTE: In limited testing, the volume letter subkeys beneath the +# BitBucket key appear to be volatile. +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package bitbucket_user; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20091020); + +sub getConfig{return %config} + +sub getShortDescr { + return "TEST - Get user BitBucket values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching bitbucket_user v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($key_path."\\".$s->get_name()); + ::rptMsg("LastWrite Time = ".gmtime($s->get_timestamp())." (UTC)"); + eval { + my $purge = $s->get_value("NeedToPurge")->get_data(); + ::rptMsg(" NeedToPurge = ".$purge); + }; + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/brisv.pl b/thirdparty/rr/plugins/brisv.pl new file mode 100644 index 0000000000000000000000000000000000000000..c79aa3e651b96b883cf354406c7cfe0b2169f5bb --- /dev/null +++ b/thirdparty/rr/plugins/brisv.pl @@ -0,0 +1,63 @@ +#----------------------------------------------------------- +# brisv.pl +# Plugin to detect the presence of Trojan.Brisv.A +# Symantec write-up: http://www.symantec.com/security_response/writeup.jsp +# ?docid=2008-071823-1655-99 +# +# Change History: +# 20090210: Created +# +# Info on URLAndExitCommandsEnabled value: +# http://support.microsoft.com/kb/828026 +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package brisv; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090210); + +sub getConfig{return %config} + +sub getShortDescr { + return "Detect artifacts of a Troj\.Brisv\.A infection"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching brisv v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\PIMSRV"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $mp_path = "Software\\Microsoft\\MediaPlayer\\Preferences"; + my $url; + eval { + $url = $key->get_subkey($mp_path)->get_value("URLAndExitCommandsEnabled")->get_data(); + ::rptMsg($mp_path."\\URLAndExitCommandsEnabled value set to ".$url); + }; +# if an error occurs within the eval{} statement, do nothing + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/clampi.pl b/thirdparty/rr/plugins/clampi.pl new file mode 100644 index 0000000000000000000000000000000000000000..abf0ae537a2cf3b0d86637396bed5b10165ca2a7 --- /dev/null +++ b/thirdparty/rr/plugins/clampi.pl @@ -0,0 +1,120 @@ +#----------------------------------------------------------- +# clampi.pl +# Checks keys/values set by new version of Trojan.Clampi +# +# Change history +# 20091019 - created +# +# NOTE: This is purely a test plugin, and based solely on the below +# reference. It has not been tested on any systems that were +# known to be infected. +# +# References +# http://www.symantec.com/connect/blogs/inside-trojanclampi-stealing-your-information +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package clampi; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20091019); + +sub getConfig{return %config} +sub getShortDescr { + return "TEST - Checks for keys set by Trojan\.Clampi PROT module"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching clampi v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $count = 0; + + my $key_path = 'Software\\Microsoft\\Internet Explorer\\Main'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my ($form1, $form2, $form3); + + eval { + $form1 = $key->get_value("Use FormSuggest")->get_data(); + ::rptMsg("\tUse FormSuggest = ".$form1); + $count++ if ($form1 eq "true"); + }; + + eval { + $form2 = $key->get_value("FormSuggest_Passwords")->get_data(); + ::rptMsg("\tFormSuggest_Passwords = ".$form2); + $count++ if ($form2 eq "true"); + }; + + eval { + $form3 = $key->get_value("FormSuggest_PW_Ask")->get_data(); + ::rptMsg("\tUse FormSuggest = ".$form3); + $count++ if ($form3 eq "no"); + }; + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoComplete"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $auto; + eval { + $auto = $key->get_value("AutoSuggest")->get_data(); + ::rptMsg("\tAutoSuggest = ".$auto); + $count++ if ($auto eq "true"); + }; + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); + my $key_path = "Software\\Microsoft\\Internet Account Manager\\Accounts"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $prompt; + eval { + $prompt = $key->get_value("POP3 Prompt for Password")->get_data(); + ::rptMsg("\tPOP3 Prompt for Password = ".$prompt); + $count++ if ($prompt eq "true"); + }; + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); + if ($count == 5) { + ::rptMsg("The system may have been infected with the Trojan.Clampi PROT module."); + } + else { + ::rptMsg("The system does not appear to have been infected with the Trojan.Clampi"); + ::rptMsg("PROT module."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/clampitm.pl b/thirdparty/rr/plugins/clampitm.pl new file mode 100644 index 0000000000000000000000000000000000000000..60f21738c684074b9b8257ef249937b0826b001e --- /dev/null +++ b/thirdparty/rr/plugins/clampitm.pl @@ -0,0 +1,78 @@ +#----------------------------------------------------------- +# clampitm.pl +# Checks keys/values set by new version of Trojan.Clampi +# +# Change history +# 20100624 - created +# +# NOTE: This is purely a test plugin, and based solely on the below +# reference. It has not been tested on any systems that were +# known to be infected. +# +# References +# http://us.trendmicro.com/imperia/md/content/us/trendwatch/researchandanalysis/ilomo_external.pdf +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package clampitm; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100624); + +sub getConfig{return %config} +sub getShortDescr { + return "Checks for IOCs for Clampi (per Trend Micro)"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching clampitm v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $count = 0; + + my $key_path = 'Software\\Microsoft\\Internet Explorer\\Settings'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ClampiTM plugin"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $tag = 1; + my @list = qw/GatesList GID KeyE KeyM PID/; + my @vals = $key->get_list_of_values(); + if (scalar (@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + if (grep(/$name/,@list)) { + ::rptMsg(sprintf "%-10s %-30s",$name,$v->get_data()); + $tag = 0; + } + } + if ($tag) { + ::rptMsg("No Clampi values found."); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/clsid.pl b/thirdparty/rr/plugins/clsid.pl new file mode 100644 index 0000000000000000000000000000000000000000..1823600295ed2e2dbda5fe40215968feb4e4970e --- /dev/null +++ b/thirdparty/rr/plugins/clsid.pl @@ -0,0 +1,80 @@ +#----------------------------------------------------------- +# clsid.pl +# Plugin to extract file association data from the Software hive file +# Can take considerable time to run; recommend running it via rip.exe +# +# History +# 20100227 - created +# +# References +# http://msdn.microsoft.com/en-us/library/ms724475%28VS.85%29.aspx +# +# copyright 2010, Quantum Analytics Research, LLC +#----------------------------------------------------------- +package clsid; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100227); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get list of CLSID/registered classes"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %clsid; + ::logMsg("Launching clsid v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Classes\\CLSID"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); +# First step will be to get a list of all of the file extensions + my %ext; + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + + my $name = $s->get_name(); + eval { + my $n = $s->get_value("")->get_data(); + $name .= " ".$n unless ($n eq ""); + }; + + push(@{$clsid{$s->get_timestamp()}},$name); + } + + foreach my $t (reverse sort {$a <=> $b} keys %clsid) { + ::rptMsg(gmtime($t)." Z"); + foreach my $item (@{$clsid{$t}}) { + ::rptMsg(" ".$item); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/cmd_shell.pl b/thirdparty/rr/plugins/cmd_shell.pl new file mode 100644 index 0000000000000000000000000000000000000000..84e40a7735e64d3579b540ae601b181be8b7a4b3 --- /dev/null +++ b/thirdparty/rr/plugins/cmd_shell.pl @@ -0,0 +1,75 @@ +#----------------------------------------------------------- +# cmd_shell +# +# +# Change History +# 20100830 - added "cs" shell command to the path +# 20080328 - created +# +# References +# http://www.microsoft.com/security/portal/Threat/Encyclopedia/Entry.aspx? +# Name=TrojanClicker%3AWin32%2FVB.GE +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package cmd_shell; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20100830); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets shell open cmds for various file types"; +} +sub getDescr{} +sub getRefs { + my %refs = ("You Are Unable to Start a Program with an .exe File Extension" => + "http://support.microsoft.com/kb/310585"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching cmd_shell v.".$VERSION); + + my @shells = ("exe","cmd","bat","cs","hta","pif"); + + foreach my $sh (@shells) { + + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Classes\\".$sh."file\\shell\\open\\command"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("cmd_shell"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $val; + eval { + $val = $key->get_value("")->get_data(); + ::rptMsg("\tCmd: ".$val); + }; + ::rptMsg("Error: ".$@) if ($@); + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + } + ::rptMsg(""); +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/codeid.pl b/thirdparty/rr/plugins/codeid.pl new file mode 100644 index 0000000000000000000000000000000000000000..f3eec03151a3bc6221003658057ab3e876cf19a4 --- /dev/null +++ b/thirdparty/rr/plugins/codeid.pl @@ -0,0 +1,75 @@ +#----------------------------------------------------------- +# codeid +# Get DefaultLevel value from CodeIdentifiers key +# +# +# Change History +# 20100608 - created +# +# References +# SANS ISC blog - http://isc.sans.edu/diary.html?storyid=8917 +# CodeIdentifiers key +# - http://technet.microsoft.com/en-us/library/bb457006.aspx +# SAFER_LEVELID_FULLYTRUSTED value +# - http://msdn.microsoft.com/en-us/library/ms722424%28VS.85%29.aspx +# (262144 == Unrestricted) +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package codeid; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100608); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets CodeIdentifier DefaultLevel value"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching codeid v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Policies\\Microsoft\\Windows\\Safer\\CodeIdentifiers"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("CodeID"); + ::rptMsg($key_path); + my $lastwrite = $key->get_timestamp(); + ::rptMsg(" LastWrite time: ".gmtime($lastwrite)." Z"); + ::rptMsg(""); + + my $level; + eval { + $level = $key->get_value("DefaultLevel")->get_data(); + ::rptMsg(sprintf "DefaultLevel = 0x%08x",$level); + }; + + my $exe; + eval { + $exe = $key->get_value("ExecutableTypes")->get_data(); + $exe =~ s/\s/,/g; + ::rptMsg("ExecutableTypes = ".$exe); + + }; + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/comdlg32.pl b/thirdparty/rr/plugins/comdlg32.pl new file mode 100644 index 0000000000000000000000000000000000000000..61cda3c1e6b8163122b175417e6776a27a2ad1a3 --- /dev/null +++ b/thirdparty/rr/plugins/comdlg32.pl @@ -0,0 +1,145 @@ +#----------------------------------------------------------- +# comdlg32.pl +# Plugin for Registry Ripper +# +# Change history +# 20100402 - updated IAW Chad Tilbury's post to SANS +# Forensic Blog +# 20080324 - created +# +# References +# Win2000 - http://support.microsoft.com/kb/319958 +# XP - http://support.microsoft.com/kb/322948/EN-US/ +# +# copyright 20100402 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package comdlg32; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100402); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's ComDlg32 key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching comdlg32 v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + ::rptMsg("comdlg32 v.".$VERSION); + +# LastVistedMRU + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU"; + my $key; + my @vals; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ComDlg32\\LastVisitedMRU"); + ::rptMsg("**All values printed in MRUList order."); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my %lvmru; + my @mrulist; + @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { +# First, read in all of the values and the data + foreach my $v (@vals) { + $lvmru{$v->get_name()} = $v->get_data(); + } +# Then, remove the MRUList value + if (exists $lvmru{MRUList}) { + ::rptMsg(" MRUList = ".$lvmru{MRUList}); + @mrulist = split(//,$lvmru{MRUList}); + delete($lvmru{MRUList}); + foreach my $m (@mrulist) { + my ($file,$dir) = split(/\00\00/,$lvmru{$m},2); + $file =~ s/\00//g; + $dir =~ s/\00//g; + ::rptMsg(" ".$m." -> EXE: ".$file); + ::rptMsg(" -> Last Dir: ".$dir); + } + } + else { + ::rptMsg($key_path." does not have an MRUList value."); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); + +# OpenSaveMRU + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU"; + my $key; + my @vals; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ComDlg32\\OpenSaveMRU"); + ::rptMsg("**All values printed in MRUList order."); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); +# First, process OpenSaveMRU key values + parseOpenSaveValues($key); + ::rptMsg(""); +# Now, let's get the subkeys + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + parseOpenSaveValues($s); + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub parseOpenSaveValues { + my $key = shift; + ::rptMsg("OpenSaveMRU\\".$key->get_name()); + ::rptMsg("LastWrite Time: ".gmtime($key->get_timestamp())." Z"); + my %osmru; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + map{$osmru{$_->get_name()} = $_->get_data()}(@vals); + if (exists $osmru{MRUList}) { + ::rptMsg(" MRUList = ".$osmru{MRUList}); + my @mrulist = split(//,$osmru{MRUList}); + delete($osmru{MRUList}); + foreach my $m (@mrulist) { + ::rptMsg(" ".$m." -> ".$osmru{$m}); + } + } + else { + ::rptMsg($key->get_name()." does not have an MRUList value."); + } + } + else { + ::rptMsg($key->get_name()." has no values."); + } +} + + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/comdlg32a.pl b/thirdparty/rr/plugins/comdlg32a.pl new file mode 100644 index 0000000000000000000000000000000000000000..0187b945d53c5ff7b28cbdd9c6aca5d3550f1970 --- /dev/null +++ b/thirdparty/rr/plugins/comdlg32a.pl @@ -0,0 +1,225 @@ +#----------------------------------------------------------- +# comdlg32a.pl +# Plugin for Registry Ripper +# +# Change history +# 20100409 - updated to include Vista and above +# 20100402 - updated IAW Chad Tilbury's post to SANS +# Forensic Blog +# 20080324 - created +# +# References +# Win2000 - http://support.microsoft.com/kb/319958 +# XP - http://support.microsoft.com/kb/322948/EN-US/ +# +# copyright 20100402 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package comdlg32a; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100409); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's ComDlg32 key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching comdlg32a v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + ::rptMsg("comdlg32 v.".$VERSION); + +# LastVistedMRU + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32"; + my $key; + my @vals; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @subkeys = $key->get_list_of_subkeys(); + + if (scalar @subkeys > 0) { + foreach my $s (@subkeys) { + parseLastVisitedMRU($s) if ($s->get_name() eq "LastVisitedMRU"); + parseOpenSaveMRU($s) if ($s->get_name() eq "OpenSaveMRU"); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } +} + +sub parseLastVisitedMRU { + my $key = shift; + my %lvmru; + my @mrulist; + my @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { +# First, read in all of the values and the data + foreach my $v (@vals) { + $lvmru{$v->get_name()} = $v->get_data(); + } +# Then, remove the MRUList value + if (exists $lvmru{MRUList}) { + ::rptMsg(" MRUList = ".$lvmru{MRUList}); + @mrulist = split(//,$lvmru{MRUList}); + delete($lvmru{MRUList}); + foreach my $m (@mrulist) { + my ($file,$dir) = split(/\00\00/,$lvmru{$m},2); + $file =~ s/\00//g; + $dir =~ s/\00//g; + ::rptMsg(" ".$m." -> EXE: ".$file); + ::rptMsg(" -> Last Dir: ".$dir); + } + } + else { + ::rptMsg("LastVisitedMRU key does not have an MRUList value."); + } + } + else { + ::rptMsg("LastVisitedMRU key has no values."); + } + ::rptMsg(""); +} + +sub parseOpenSaveMRU { + my $key = shift; + + parseOpenSaveValues($key); + ::rptMsg(""); +# Now, let's get the subkeys + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + parseOpenSaveValues($s); + ::rptMsg(""); + } + } + else { + ::rptMsg("OpenSaveMRU key has no subkeys."); + } + ::rptMsg(""); +} + +sub parseOpenSaveValues { + my $key = shift; + ::rptMsg("OpenSaveMRU\\".$key->get_name()); + ::rptMsg("LastWrite Time: ".gmtime($key->get_timestamp())." Z"); + my %osmru; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + map{$osmru{$_->get_name()} = $_->get_data()}(@vals); + if (exists $osmru{MRUList}) { + ::rptMsg(" MRUList = ".$osmru{MRUList}); + my @mrulist = split(//,$osmru{MRUList}); + delete($osmru{MRUList}); + foreach my $m (@mrulist) { + ::rptMsg(" ".$m." -> ".$osmru{$m}); + } + } + else { + ::rptMsg($key->get_name()." does not have an MRUList value."); + } + } + else { + ::rptMsg($key->get_name()." has no values."); + } +} + +sub parseCIDSizeMRU { + my $key = shift; + my %lvmru; + my @mrulist; + my @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { +# First, read in all of the values and the data + foreach my $v (@vals) { + $lvmru{$v->get_name()} = $v->get_data(); + } +# Then, remove the MRUList value + if (exists $lvmru{MRUListEx}) { + delete($lvmru{MRUListEx}); + foreach my $m (keys %lvmru) { + my $file = parseStr($lvmru{$m}); + my $str = sprintf "%-4s ".$file,$m; + ::rptMsg(" ".$str); + } + } + else { + ::rptMsg($key_path." does not have an MRUList value."); + } + } + else { + ::rptMsg($key_path." has no values."); + } +} + + +sub parseLastVisitedPidlMRU { + my $key = shift; + my %lvmru; + my @mrulist; + @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { +# First, read in all of the values and the data + foreach my $v (@vals) { + $lvmru{$v->get_name()} = $v->get_data(); + } +# Then, remove the MRUList value + if (exists $lvmru{MRUListEx}) { + delete($lvmru{MRUListEx}); + foreach my $m (keys %lvmru) { + my $file = parseStr($lvmru{$m}); + my $str = sprintf "%-4s ".$file,$m; + ::rptMsg(" ".$str); + } + } + else { + ::rptMsg("LastVisitedPidlMRU key does not have an MRUList value."); + } + } + else { + ::rptMsg("LastVisitedPidlMRU key has no values."); + } +} + +sub parseStr { + my $data = $_[0]; + my $temp; + my $tag = 1; + my $ofs = 0; + + while ($tag) { + my $t = substr($data,$ofs,2); + if (unpack("v",$t) == 0x00) { + $tag = 0; + } + else { + $temp .= $t; + $ofs += 2; + } + } + $temp =~ s/\00//g; + return $temp; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/compdesc.pl b/thirdparty/rr/plugins/compdesc.pl new file mode 100644 index 0000000000000000000000000000000000000000..fc1f2920891e1517b0d02bc1263ea9539d4a3d39 --- /dev/null +++ b/thirdparty/rr/plugins/compdesc.pl @@ -0,0 +1,65 @@ +#----------------------------------------------------------- +# compdesc.pl +# Plugin for Registry Ripper, +# ComputerDescriptions key parser +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package compdesc; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's ComputerDescriptions key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching compdesc v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComputerDescriptions'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ComputerDescriptions"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + ::rptMsg(" ".$v->get_name()." ".$v->get_data()); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/compname.pl b/thirdparty/rr/plugins/compname.pl new file mode 100644 index 0000000000000000000000000000000000000000..b07c44183c6595f602539a479c7328a4eea2b739 --- /dev/null +++ b/thirdparty/rr/plugins/compname.pl @@ -0,0 +1,75 @@ +#----------------------------------------------------------- +# compname.pl +# Plugin for Registry Ripper; Access System hive file to get the +# computername +# +# Change history +# 20090727 - added Hostname +# +# References +# http://support.microsoft.com/kb/314053/ +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package compname; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090727); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets ComputerName and Hostname values from System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching compname v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my ($current,$ccs); + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + my $cn_path = $ccs."\\Control\\ComputerName\\ComputerName"; + my $cn; + if ($cn = $root_key->get_subkey($cn_path)) { + my $name = $cn->get_value("ComputerName")->get_data(); + ::rptMsg("ComputerName = ".$name); + } + else { + ::rptMsg($cn_path." not found."); + ::logMsg($cn_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + + my $hostname; + eval { + my $host_path = $ccs."\\Services\\Tcpip\\Parameters"; + $hostname = $root_key->get_subkey($host_path)->get_value("Hostname")->get_data(); + ::rptMsg("TCP/IP Hostname = ".$hostname); + }; + +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/controlpanel.pl b/thirdparty/rr/plugins/controlpanel.pl new file mode 100644 index 0000000000000000000000000000000000000000..67e06a906ab78e7f6463d4875acc5ec779b91962 --- /dev/null +++ b/thirdparty/rr/plugins/controlpanel.pl @@ -0,0 +1,64 @@ +#----------------------------------------------------------- +# controlpanel.pl +# Vista ControlPanel key seems to contain some interesting info about the +# user's activities... +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package controlpanel; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 64, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080428); + +sub getConfig{return %config} + +sub getShortDescr { + return "Look for RecentTask* values in ControlPanel key (Vista)"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching controlpanel v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + ::rptMsg("Analysis Tip: The RecentTask* entries appear to only be populated through the"); + ::rptMsg("choices in the Control Panel Home view (in Vista). As each new choice is"); + ::rptMsg("selected, the most recent choice is added as RecentTask1, and each "); + ::rptMsg("RecentTask* entry is incremented and pushed down in the stack."); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $str = sprintf "%-15s %-45s",$v->get_name(),$v->get_data(); + ::rptMsg($str); + } + ::rptMsg(""); + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/cpldontload.pl b/thirdparty/rr/plugins/cpldontload.pl new file mode 100644 index 0000000000000000000000000000000000000000..620419ef9b83f3be5c61c8cbce235d6b597e28dd --- /dev/null +++ b/thirdparty/rr/plugins/cpldontload.pl @@ -0,0 +1,72 @@ +#----------------------------------------------------------- +# cpldontload.pl +# Check contents of user's Control Panel\don't load key +# +# Change history +# 20100116 - created +# +# References +# W32.Nekat - http://www.symantec.com/security_response/ +# writeup.jsp?docid=2008-011419-0705-99&tabid=2 +# http://www.2-viruses.com/remove-antispywarexp2009 +# +# Notes: Some malware appears to hide various Control Panel applets +# using this means. If some sort of malware/spyware is thought +# to be on the system, check the settings and note the key +# LastWrite time. +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package cpldontload; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100116); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's Control Panel don't load key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching cpldontload v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Control Panel\\don\'t load"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @vals = $key->get_list_of_values(); + if (scalar @vals > 0) { + foreach my $v (@vals) { + my $str = sprintf "%-20s %-5s",$v->get_name(),$v->get_data(); + ::rptMsg($str); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/crashcontrol.pl b/thirdparty/rr/plugins/crashcontrol.pl new file mode 100644 index 0000000000000000000000000000000000000000..61cc30b815efa77b47ddf0066a475203a3fa219a --- /dev/null +++ b/thirdparty/rr/plugins/crashcontrol.pl @@ -0,0 +1,93 @@ +#----------------------------------------------------------- +# crashcontrol.pl +# +# Ref: +# http://support.microsoft.com/kb/254649 +# http://support.microsoft.com/kb/274598 +# +# copyright 2008-2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package crashcontrol; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081212); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get crash control information"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my %dumpenabled = (0 => "None", + 1 => "Complete memory dump", + 2 => "Kernel memory dump", + 3 => "Small (64kb) memory dump"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching crashcontrol v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + + my $cc_path = "ControlSet00".$current."\\Control\\CrashControl"; + my $cc; + + if ($cc = $root_key->get_subkey($cc_path)) { + + eval { + my $cde = $cc->get_value("CrashDumpEnabled")->get_data(); + ::rptMsg("CrashDumpEnabled = ".$cde." [".$dumpenabled{$cde}."]"); + }; + + eval { + my $df = $cc->get_value("DumpFile")->get_data(); + ::rptMsg("DumpFile = ".$df); + }; + + eval { + my $mini = $cc->get_value("MinidumpDir")->get_data(); + ::rptMsg("MinidumpDir = ".$mini); + }; + + eval { + my $logevt = $cc->get_value("LogEvent")->get_data(); + ::rptMsg("LogEvent = ".$logevt); + ::rptMsg(" Logs an event to the System Event Log (event ID = 1001, source = Save Dump)") if ($logevt == 1); + }; + + eval { + my $sendalert = $cc->get_value("SendAlert")->get_data(); + ::rptMsg("SendAlert = ".$sendalert); + ::rptMsg(" Sends a \'net send\' pop-up if a crash occurs") if ($sendalert == 1); + }; + + + } + else { + ::rptMsg($cc_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; diff --git a/thirdparty/rr/plugins/crashdump.pl b/thirdparty/rr/plugins/crashdump.pl new file mode 100644 index 0000000000000000000000000000000000000000..eea639e8271ebcc42850f2abf191162ab8a9ebe5 --- /dev/null +++ b/thirdparty/rr/plugins/crashdump.pl @@ -0,0 +1,115 @@ +#----------------------------------------------------------- +# crashdump.pl +# Author: Don C. Weber +# Plugin for Registry Ripper; Access System hive file to get the +# crashdump settings from System hive +# +# Change history +# +# +# References +# Overview of memory dump file options for Windows Server 2003, Windows XP, and Windows 2000: http://support.microsoft.com/kb/254649/ +# +# Author: Don C. Weber, http://www.cutawaysecurity.com/blog/cutaway-security +#----------------------------------------------------------- +package crashdump; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081219); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets crashdump settings from System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching crashdump v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $win_path = $ccs."\\Control\\CrashControl"; + my $win; + if ($win = $root_key->get_subkey($win_path)) { + ::rptMsg("CrashControl Configuration"); + ::rptMsg($win_path); + ::rptMsg("LastWrite Time ".gmtime($win->get_timestamp())." (UTC)"); + } + else { + ::rptMsg($win_path." not found."); + } + + my %vals = getKeyValues($win); + if (scalar(keys %vals) > 0) { + foreach my $v (keys %vals) { + if ($v eq "CrashDumpEnabled"){ + if ($vals{$v} == 0x00){ + ::rptMsg("\t".$v." -> None"); + } elsif ($vals{$v} == 0x01){ + ::rptMsg("\t".$v." -> Complete memory dump"); + } elsif ($vals{$v} == 0x02){ + ::rptMsg("\t".$v." -> Kernel memory dump"); + } elsif ($vals{$v} == 0x03){ + ::rptMsg("\t".$v." -> Small memory dump (64KB)"); + } else{ + ::rptMsg($v." has no value."); + } + }else{ + if (($v eq "MinidumpDir") || ($v eq "DumpFile")){ + ::rptMsg("\t".$v." location ".$vals{$v}); + } else{ + ($vals{$v}) ? ::rptMsg("\t".$v." is Enabled") : ::rptMsg("\t".$v." is Disabled"); + } + } + } + } + else { +# ::rptMsg($key_path." has no values."); + } + ::rptMsg(""); + ::rptMsg("Analysis Tips: For crash dump information and tools check http://support.microsoft.com/kb/254649/"); + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +sub getKeyValues { + my $key = shift; + my %vals; + + my @vk = $key->get_list_of_values(); + if (scalar(@vk) > 0) { + foreach my $v (@vk) { + next if ($v->get_name() eq "" && $v->get_data() eq ""); + $vals{$v->get_name()} = $v->get_data(); + } + } + else { + + } + return %vals; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ctrlpnl.pl b/thirdparty/rr/plugins/ctrlpnl.pl new file mode 100644 index 0000000000000000000000000000000000000000..13ce7bf906b6722e23a7955ab5329d34998efcc1 --- /dev/null +++ b/thirdparty/rr/plugins/ctrlpnl.pl @@ -0,0 +1,143 @@ +#----------------------------------------------------------- +# ctrlpnl.pl +# Get Control Panel info from the Software hive +# +# Change history: +# 20100116 - created +# +# References: +# http://support.microsoft.com/kb/292463 +# http://learning.infocollections.com/ebook%202/Computer/ +# Operating%20Systems/Windows/Windows.XP.Hacks/ +# 0596005113_winxphks-chp-2-sect-3.html +# http://msdn.microsoft.com/en-us/library/cc144195%28VS.85%29.aspx +# +# Notes: +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package ctrlpnl; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100116); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get Control Panel info from Software hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %comp; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching ctrlpnl v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Control Panel"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg(""); + +# Cpls section + if (my $cpl = $key->get_subkey("Cpls")) { + my @vals = $cpl->get_list_of_values(); + if (scalar @vals > 0) { + ::rptMsg("Cpls key"); + foreach my $v (@vals) { + my $str = sprintf "%-10s %-50s",$v->get_name(),$v->get_data(); + ::rptMsg($str); + } + ::rptMsg(""); + } + else { + ::rptMsg("Cpls key has no values."); + } + } + else { + ::rptMsg("Cpls key not found."); + } + +# don't load section +# The 'don't load' key prevents applets from being loaded +# Be sure to check the user's don't load key, as well + if (my $cpl = $key->get_subkey("don't load")) { + my @vals = $cpl->get_list_of_values(); + if (scalar @vals > 0) { + ::rptMsg("don't load key"); + foreach my $v (@vals) { + ::rptMsg($v->get_name()); + } + ::rptMsg(""); + } + else { + ::rptMsg("don't load key has no values."); + } + } + else { + ::rptMsg("don't load key not found."); + } + +# Extended Properties section + if (my $ext = $key->get_subkey("Extended Properties")) { + my @sk = $ext->get_list_of_subkeys(); + if (scalar @sk > 0) { + foreach my $s (@sk) { + my @vals = $s->get_list_of_values(); + if (scalar @vals > 0) { + ::rptMsg($s->get_name()." [".gmtime($s->get_timestamp)." UTC]"); + +# Ref: http://support.microsoft.com/kb/292463 + my %cat = (0x00000000 => "Other Control Panel Options", + 0x00000001 => "Appearance and Themes", + 0x00000002 => "Printers and Other Hardware", + 0x00000003 => "Network and Internet Connections", + 0x00000004 => "Sounds, Speech, and Audio Devices", + 0x00000005 => "Performance and Maintenance", + 0x00000006 => "Date, Time, Language, and Regional Options", + 0x00000007 => "Accessibility Options", + 0xFFFFFFFF => "No Category"); + my %prop; + foreach my $v (@vals) { + push(@{$prop{$v->get_data()}},$v->get_name()); + } + + foreach my $t (sort {$a <=> $b} keys %prop) { + (exists $cat{$t}) ? (::rptMsg($cat{$t})) : (::rptMsg("Category ".$t)); + foreach my $i (@{$prop{$t}}) { + ::rptMsg(" ".$i); + } + ::rptMsg(""); + } + } + } + ::rptMsg(""); + } + else { + ::rptMsg("Extended Properties key has no subkeys."); + } + } + else { + ::rptMsg("Extended Properties key not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ddm.pl b/thirdparty/rr/plugins/ddm.pl new file mode 100644 index 0000000000000000000000000000000000000000..e66fb2697f136bc1d1e72d62587a72fbb64d5f70 --- /dev/null +++ b/thirdparty/rr/plugins/ddm.pl @@ -0,0 +1,82 @@ +#----------------------------------------------------------- +# ddm.pl +# +# History: +# 20081129 - created +# +# Note - Not really sure what this is for or could be used for, other +# than to show devices that had been connected to the system +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package ddm; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081129); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get DDM data from Control Subkey"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching ddm v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + + my $key_path = $ccs."\\Control\\DDM"; + my $key; + my %dev; + if ($key = $root_key->get_subkey($key_path)) { + my @subkeys = $key->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + my $tag = (split(/\./,$name,2))[1]; + $dev{$tag}{timestamp} = $s->get_timestamp(); + eval { + $dev{$tag}{make} = $s->get_value("MakeName")->get_data(); + $dev{$tag}{model} = $s->get_value("ModelName")->get_data(); + }; + } + foreach my $d (sort keys %dev) { + ::rptMsg(gmtime($dev{$d}{timestamp})."Z Device\.".$d." ".$dev{$d}{make}." ".$dev{$d}{model}); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); +# ::logMsg($key_path." not found."); + } + } + else { + ::logMsg("Current value not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/defbrowser.pl b/thirdparty/rr/plugins/defbrowser.pl new file mode 100644 index 0000000000000000000000000000000000000000..ae7055aba152e5a6eeb6c88560762c357d9d577f --- /dev/null +++ b/thirdparty/rr/plugins/defbrowser.pl @@ -0,0 +1,78 @@ +#----------------------------------------------------------- +# defbrowser.pl +# Get default browser information - check #1 can apply to HKLM +# as well as to HKCU +# +# Change History: +# 20091116 - Added Check #1 +# 20081105 - created +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package defbrowser; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20091116); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets default browser setting from HKLM"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching defbrowser v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Clients\\StartMenuInternet"; + if (my $key = $root_key->get_subkey($key_path)) { + ::rptMsg("Default Browser Check #1"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $browser = $key->get_value("")->get_data(); + ::rptMsg("Default Browser : ".$browser); + } + else { + ::rptMsg($key_path." not found."); + } + + ::rptMsg(""); + + my $key_path = "Classes\\HTTP\\shell\\open\\command"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Default Browser Check #2"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $browser; + eval { + $browser = $key->get_value("")->get_data(); + }; + if ($@) { + ::rptMsg("Error locating default browser setting."); + } + else { + ::rptMsg("Default Browser = ".$browser); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/devclass.pl b/thirdparty/rr/plugins/devclass.pl new file mode 100644 index 0000000000000000000000000000000000000000..b6a57fff2f46c234388e6c8ad44637efd1f7df5f --- /dev/null +++ b/thirdparty/rr/plugins/devclass.pl @@ -0,0 +1,125 @@ +#----------------------------------------------------------- +# devclass +# Get USB device info from the DeviceClasses keys in the System +# hive (Disks and Volumes GUIDs) +# +# Change History: +# 20100901 - spelling error in output corrected +# 20080331 - created +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package devclass; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100901); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get USB device info from the DeviceClasses keys in the System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching devclass v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::logMsg("Could not find ".$key_path); + return + } +# Get devices from the Disk GUID + my $key_path = $ccs."\\Control\\DeviceClasses\\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("DevClasses - Disks"); + ::rptMsg($key_path); + ::rptMsg(""); + my %disks; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + next unless (grep(/USBSTOR/,$name)); + my $lastwrite = $s->get_timestamp(); + my ($dev, $serial) = (split(/#/,$name))[4,5]; + push(@{$disks{$lastwrite}},$dev.",".$serial); + } + + foreach my $t (reverse sort {$a <=> $b} keys %disks) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$disks{$t}}) { + ::rptMsg("\t$item"); + } + } + + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + ::rptMsg(""); +# Get devices from the Volume GUID + my $key_path = $ccs."\\Control\\DeviceClasses\\{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("DevClasses - Volumes"); + ::rptMsg($key_path); + ::rptMsg(""); + my %vols; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + next unless (grep(/RemovableMedia/,$name)); + my $lastwrite = $s->get_timestamp(); + my $ppi = (split(/#/,$name))[5]; + push(@{$vols{$lastwrite}},$ppi); + } + + foreach my $t (reverse sort {$a <=> $b} keys %vols) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$vols{$t}}) { + ::rptMsg("\tParentIdPrefix: ".$item); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/dfrg.pl b/thirdparty/rr/plugins/dfrg.pl new file mode 100644 index 0000000000000000000000000000000000000000..29ac3b80ecb54fddd37b3fe37652238853e14c82 --- /dev/null +++ b/thirdparty/rr/plugins/dfrg.pl @@ -0,0 +1,63 @@ +#----------------------------------------------------------- +# dfrg.pl +# Gets contents of Dfrg\BootOptimizeFunction key +# +# Change history: +# 20110321 - created +# +# References +# http://technet.microsoft.com/en-us/library/cc784391%28WS.10%29.aspx +# +# copyright 2011 Quantum Analytics Research, LLC (keydet89@yahoo.com) +#----------------------------------------------------------- +package dfrg; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20110321); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets content of Dfrg BootOptim. key"; +} +sub getDescr{} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching dfrg v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Dfrg\\BootOptimizeFunction"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Dfrg"); + ::rptMsg($key_path); + ::rptMsg(""); + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + ::rptMsg(sprintf "%-20s %-20s",$v->get_name(),$v->get_data()); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/disablelastaccess.pl b/thirdparty/rr/plugins/disablelastaccess.pl new file mode 100644 index 0000000000000000000000000000000000000000..e064521726e80b00bd43430df1d28825bea1ac94 --- /dev/null +++ b/thirdparty/rr/plugins/disablelastaccess.pl @@ -0,0 +1,73 @@ +#----------------------------------------------------------- +# disablelastaccess.pl +# +# References: +# http://support.microsoft.com/kb/555041 +# http://support.microsoft.com/kb/894372 +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package disablelastaccess; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090118); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get NTFSDisableLastAccessUpdate value"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching disablelastaccess v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + my $ccs; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + + my $key_path = $ccs."\\Control\\FileSystem"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("NtfsDisableLastAccessUpdate"); + ::rptMsg($key_path); + my @vals = $key->get_list_of_values(); + my $found = 0; + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + if ($v->get_name() eq "NtfsDisableLastAccessUpdate") { + ::rptMsg("NtfsDisableLastAccessUpdate = ".$v->get_data()); + $found = 1; + } + } + ::rptMsg("NtfsDisableLastAccessUpdate value not found.") if ($found == 0); + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/dllsearch.pl b/thirdparty/rr/plugins/dllsearch.pl new file mode 100644 index 0000000000000000000000000000000000000000..767042a8ec3c32ea7fcf4ba4b3ad242714e86014 --- /dev/null +++ b/thirdparty/rr/plugins/dllsearch.pl @@ -0,0 +1,69 @@ +#----------------------------------------------------------- +# dllsearch.pl +# +# References: +# http://support.microsoft.com/kb/2264107 +# +# Change History: +# 20100824: created +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package dllsearch; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100824); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get crash control information"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching dllsearch v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + + my $cc_path = "ControlSet00".$current."\\Control\\Session Manager"; + my $cc; + if ($cc = $root_key->get_subkey($cc_path)) { + ::rptMsg("dllsearch v.".$VERSION); + ::rptMsg(""); + my $found = 1; + eval { + my $cde = $cc->get_value("CWDIllegalInDllSearch")->get_data(); + $found = 0; + ::rptMsg(sprintf "CWDIllegalInDllSearch = 0x%x",$cde); + }; + ::rptMsg("CWDIllegalInDllSearch value not found.") if ($found); + } + else { + ::rptMsg($cc_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; diff --git a/thirdparty/rr/plugins/domains.pl b/thirdparty/rr/plugins/domains.pl new file mode 100644 index 0000000000000000000000000000000000000000..633ad87cfd68705d005d748628fd01961dc11874 --- /dev/null +++ b/thirdparty/rr/plugins/domains.pl @@ -0,0 +1,74 @@ +#----------------------------------------------------------- +# domains.pl +# +# +# Change history +# 20100116 - Created +# +# References +# http://support.microsoft.com/kb/919748 +# http://support.microsoft.com/kb/922704 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package domains; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100116); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents Internet Settings\\ZoneMap\\Domains key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching domains v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap"; + my $key; + if ($key = $root_key->get_subkey($key_path."\\Domains")) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($s->get_name()." [".gmtime($s->get_timestamp())." (UTC)]"); + + my @vals = $s->get_list_of_values(); + if (scalar @vals > 0) { + foreach my $v (@vals) { + ::rptMsg(" ".$v->get_name()." -> ".$v->get_data); + } + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/drwatson.pl b/thirdparty/rr/plugins/drwatson.pl new file mode 100644 index 0000000000000000000000000000000000000000..0360c33fb35de97916aef72bea07952055cd3641 --- /dev/null +++ b/thirdparty/rr/plugins/drwatson.pl @@ -0,0 +1,77 @@ +#----------------------------------------------------------- +# drwatson.pl +# Author: Don C. Weber +# Plugin for Registry Ripper; Access Software hive file to get the +# Dr. Watson settings from Software hive +# +# Change history +# +# +# References +# Dr Watson: http://www.windowsnetworking.com/kbase/WindowsTips/Windows2000/RegistryTips/RegistryTools/DrWatson.html +# +# Author: Don C. Weber, http://www.cutawaysecurity.com/blog/cutaway-security +#----------------------------------------------------------- +package drwatson; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081219); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Dr. Watson settings from Software hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching drwatson v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\AeDebug"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ($key->get_value('Auto') == 0x0) ? ::rptMsg("Debugging is Disabled") : ::rptMsg("Debugging is Enabled"); + eval { + ::rptMsg("Debugger: ".$key->get_value('Debugger')->get_data()); + }; + + } else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + + ::rptMsg(""); + my $key_path = "Microsoft\\DrWatson"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ($key->get_value('LogFilePath')) ? ::rptMsg("DrWatson LogFile Path location: ".$key->get_value('LogFilePath')->get_data()) : ::rptMsg("DrWatson LogFile Path location: %SystemRoot%\\Documents and Settings\\All Users\\Documents\\DrWatson"); + ($key->get_value('CreateCrashDump') == 0x0) ? ::rptMsg("CreateCrashDump is Disabled") : ::rptMsg("CreateCrashDump is Enabled"); + ($key->get_value('CrashDumpFile')) ? ::rptMsg("Crash Dump Path and Name: ".$key->get_value('CrashDumpFile')->get_data()) : ::rptMsg("CrashDumpFile is not set"); + ($key->get_value('AppendToLogFile') == 0x0) ? ::rptMsg("AppendToLogFile is set to create a new file each time") : ::rptMsg("AppendToLogFile is set to append"); + + } else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + + ::rptMsg(""); + ::rptMsg("Analysis Tips: For Dr. Watson settings information check: http://www.windowsnetworking.com/kbase/WindowsTips/Windows2000/RegistryTips/RegistryTools/DrWatson.html"); +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/esent.pl b/thirdparty/rr/plugins/esent.pl new file mode 100644 index 0000000000000000000000000000000000000000..4ae7cd21b50eeb02b949e46d7aaf69bb880929e6 --- /dev/null +++ b/thirdparty/rr/plugins/esent.pl @@ -0,0 +1,78 @@ +#----------------------------------------------------------- +# esent +# Get contents of Esent\Process key from Software hive +# +# Note: Not sure why I wrote this one; just thought it might come +# in handy as info about this key is developed. +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package esent; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20101202); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get ESENT\\Process key contents"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching esent v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\ESENT\\Process"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @sk = $key->get_list_of_subkeys(); + + if (scalar(@sk) > 0) { + my %esent; + + foreach my $s (@sk) { + my $sk = $s->get_subkey("DEBUG"); +# my $lw = $s->get_timestamp(); + my $lw = $sk->get_timestamp(); + + my $name = $s->get_name(); + + push(@{$esent{$lw}},$name); + } + + foreach my $t (reverse sort {$a <=> $b} keys %esent) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$esent{$t}}) { + ::rptMsg(" $item"); + } + } + + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/eventlog.pl b/thirdparty/rr/plugins/eventlog.pl new file mode 100644 index 0000000000000000000000000000000000000000..a51ca91282c548190f94c535cc567d8f0d5ecedb --- /dev/null +++ b/thirdparty/rr/plugins/eventlog.pl @@ -0,0 +1,156 @@ +#----------------------------------------------------------- +# eventlog.pl +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package eventlog; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090112); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get EventLog configuration info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching eventlog v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + + my $evt_path = "ControlSet00".$current."\\Services\\Eventlog"; + my $evt; + if ($evt = $root_key->get_subkey($evt_path)) { + ::rptMsg(""); + my @subkeys = $evt->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + my $logname = $s->get_name(); + ::rptMsg($logname." \\ ".scalar gmtime($s->get_timestamp())."Z"); + eval { + my $file = $s->get_value("File")->get_data(); + ::rptMsg(" File = ".$file); + }; + + eval { + my $display = $s->get_value("DisplayNameFile")->get_data(); + ::rptMsg(" DisplayNameFile = ".$display); + }; + + eval { + my $max = $s->get_value("MaxSize")->get_data(); + ::rptMsg(" MaxSize = ".processSize($max)); + }; + + eval { + my $ret = $s->get_value("Retention")->get_data(); + ::rptMsg(" Retention = ".processRetention($ret)); + }; + +# AutoBackupLogFiles; http://support.microsoft.com/kb/312571/ + eval { + my $auto = $s->get_value("AutoBackupLogFiles")->get_data(); + ::rptMsg(" AutoBackupLogFiles = ".$auto); + }; + +# Check WarningLevel value on Security EventLog; http://support.microsoft.com/kb/945463 + eval { + if ($logname eq "Security") { + my $wl = $s->get_value("WarningLevel")->get_data(); + ::rptMsg(" WarningLevel = ".$wl); + } + }; + + ::rptMsg(""); + } + + } + else { + ::rptMsg($evt_path." has no subkeys."); + } + } + else { + ::rptMsg($evt_path." not found."); + ::logMsg($evt_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; + +sub processSize { + my $sz = shift; + + my $kb = 1024; + my $mb = $kb * 1024; + my $gb = $mb * 1024; + + if ($sz > $gb) { + my $d = $sz/$gb; + my $l = length((split(/\./,$d,2))[0]) + 2; + return sprintf "%$l.2fGB",$d; + } + elsif ($sz > $mb) { + my $d = $sz/$mb; + my $l = length((split(/\./,$d,2))[0]) + 2; + return sprintf "%$l.2fMB",$d; + } + elsif ($sz > $kb) { + my $d = $sz/$kb; + my $l = length((split(/\./,$d,2))[0]) + 2; + return sprintf "%$l.2fKB",$d; + } + else {return $sz."B"}; +} + +sub processRetention { +# Retention maintained in seconds +# http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/ +# regentry/30709.mspx?mfr=true + my $ret = shift; + + my $min = 60; + my $hr = $min * 60; + my $day = $hr * 24; + + if ($ret > $day) { + my $d = $ret/$day; + my $l = length((split(/\./,$d,2))[0]) + 2; + return sprintf "%$l.2f days",$d; + } + elsif ($ret > $hr) { + my $d = $ret/$hr; + my $l = length((split(/\./,$d,2))[0]) + 2; + return sprintf "%$l.2f hr",$d; + } + elsif ($ret > $min) { + my $d = $ret/$min; + my $l = length((split(/\./,$d,2))[0]) + 2; + return sprintf "%$l.2f min",$d; + } + else {return $ret." sec"}; +} \ No newline at end of file diff --git a/thirdparty/rr/plugins/eventlogs.pl b/thirdparty/rr/plugins/eventlogs.pl new file mode 100644 index 0000000000000000000000000000000000000000..d7557218c2f51f823fecf6099f336cffc5cfcde7 --- /dev/null +++ b/thirdparty/rr/plugins/eventlogs.pl @@ -0,0 +1,98 @@ +#----------------------------------------------------------- +# eventlogs.pl +# Author: Don C. Weber +# Plugin for Registry Ripper; Access System hive file to get the +# Event Log settings from System hive +# +# Change history +# +# +# References +# Eventlog Key: http://msdn.microsoft.com/en-us/library/aa363648(VS.85).aspx +# +# Author: Don C. Weber, http://www.cutawaysecurity.com/blog/cutaway-security +#----------------------------------------------------------- +package eventlogs; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081219); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Event Log settings from System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching eventlogs v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $win_path = $ccs."\\Services\\Eventlog"; + my $win; + if ($win = $root_key->get_subkey($win_path)) { + ::rptMsg("EventLog Configuration"); + ::rptMsg($win_path); + ::rptMsg("LastWrite Time ".gmtime($win->get_timestamp())." (UTC)"); + my $cn; + if ($cn = $win->get_value("ComputerName")->get_data()) { + ::rptMsg("ComputerName = ".$cn); + } + else { + ::rptMsg("ComputerName value not found."); + } + } + else { + ::rptMsg($win_path." not found."); + } + +# Cycle through each type of log + my $logname; + my $evpath; + my $evlog; + my @list_logs = $win->get_list_of_subkeys(); + foreach $logname (@list_logs){ + ::rptMsg(""); + $evpath = $win_path."\\".$logname->get_name(); + if ($evlog = $root_key->get_subkey($evpath)) { + ::rptMsg(" ".$logname->get_name()." EventLog"); + ::rptMsg(" ".$evpath); + ::rptMsg(" LastWrite Time ".gmtime($evlog->get_timestamp())." (UTC)"); + ::rptMsg(" Configuration Settings"); + ::rptMsg(" Log location: ".$evlog->get_value('File')->get_data()); + ::rptMsg(" Log Size: ".$evlog->get_value('MaxSize')->get_data()." Bytes"); + ($evlog->get_value('AutoBackupLogFiles') == 0x0) ? ::rptMsg(" AutoBackupLogFiles is Disabled") : ::rptMsg(" AutoBackupLogFiles is Enabled") + } + else { + ::rptMsg($logname->get_name()." Event Log not found."); + } + } + ::rptMsg(""); + ::rptMsg("Analysis Tips: For Event Log settings information check: http://msdn.microsoft.com/en-us/library/aa363648(VS.85).aspx"); + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/fileexts.pl b/thirdparty/rr/plugins/fileexts.pl new file mode 100644 index 0000000000000000000000000000000000000000..5bd04db82565a5fb3e66c8b256f2c1177d7e42d1 --- /dev/null +++ b/thirdparty/rr/plugins/fileexts.pl @@ -0,0 +1,73 @@ +#----------------------------------------------------------- +# fileexts.pl +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package fileexts; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080818); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get user FileExts values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching fileexts v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("fileexts"); + ::rptMsg($key_path); + ::rptMsg(""); + + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + my $name = $s->get_name(); + next unless ($name =~ m/^\.\w+/); + + eval { + my $data = $s->get_subkey("OpenWithList")->get_value("MRUList")->get_data(); + if ($data =~ m/^\w/) { + ::rptMsg("File Extension: ".$name); + ::rptMsg("LastWrite: ".gmtime($s->get_subkey("OpenWithList")->get_timestamp())); + ::rptMsg("MRUList: ".$data); + my @list = split(//,$data); + foreach my $l (@list) { + my $valdata = $s->get_subkey("OpenWithList")->get_value($l)->get_data(); + ::rptMsg(" ".$l." => ".$valdata); + } + ::rptMsg(""); + } + }; + } + } + else { + ::rptMsg($key_path." does not have subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/findexes.pl b/thirdparty/rr/plugins/findexes.pl new file mode 100644 index 0000000000000000000000000000000000000000..ee2f027b35286336d93bf314c85dfa31a137329e --- /dev/null +++ b/thirdparty/rr/plugins/findexes.pl @@ -0,0 +1,95 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# findexes.pl +# Plugin for RegRipper; traverses through a Registry hive, +# looking for values with binary data types, and checks to see +# if they start with "MZ"; if so, records the value path, key +# LastWrite time, and length of the data +# +# Change history +# 20090728 - Created +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package findexes; +use strict; + +my %config = (hive => "All", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090728); + +sub getConfig{return %config} +sub getShortDescr { + return "Scans a hive file looking for binary value data that contains MZ"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %vals; +my $bin_count = 0; +my $exe_count = 0; + +sub pluginmain { + my $class = shift; + my $file = shift; + my $reg = Parse::Win32Registry->new($file); + my $root_key = $reg->get_root_key; + ::logMsg("Launching findexes v.".$VERSION); + + traverse($root_key); +# Data structure containing findings is a hash of hashes + foreach my $k (keys %vals) { + ::rptMsg("Key: ".$k." LastWrite time: ".gmtime($vals{$k}{lastwrite})); + foreach my $i (keys %{$vals{$k}}) { + next if ($i eq "lastwrite"); + ::rptMsg(" Value: ".$i." Length: ".$vals{$k}{$i}." bytes"); + } + ::rptMsg(""); + } + ::rptMsg("Number of values w/ binary data types: ".$bin_count); + ::rptMsg("Number of values w/ MZ in binary data: ".$exe_count); +} + +sub traverse { + my $key = shift; +# my $ts = $key->get_timestamp(); + + foreach my $val ($key->get_list_of_values()) { + my $type = $val->get_type(); + if ($type == 0 || $type == 3) { + $bin_count++; + my $data = $val->get_data(); +# This code looks for data that starts with MZ +# my $i = unpack("v",substr($data,0,2)); +# if ($i == 0x5a4d) { + if (grep(/MZ/,$data)) { + $exe_count++; + my $path; + my @p = split(/\\/,$key->get_path()); + if (scalar(@p) == 1) { + $path = "root"; + } + else { + shift(@p); + $path = join('\\',@p); + } + + $vals{$path}{lastwrite} = $key->get_timestamp(); + $vals{$path}{$val->get_name()} = length($data); + } + } + } + + foreach my $subkey ($key->get_list_of_subkeys()) { + traverse($subkey); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/fw_config.pl b/thirdparty/rr/plugins/fw_config.pl new file mode 100644 index 0000000000000000000000000000000000000000..e43e2458371046a53fd931d33e0a608dfa9a1bff --- /dev/null +++ b/thirdparty/rr/plugins/fw_config.pl @@ -0,0 +1,116 @@ +#----------------------------------------------------------- +# fw_config +# +# References +# http://technet2.microsoft.com/WindowsServer/en/library/47f25d7d- +# 882b-4f87-b05f-31e5664fc15e1033.mspx?mfr=true +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package fw_config; +use strict; + +my %config = (hive => "System", + osmask => 20, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080328); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets the Windows Firewall config from the System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching fw_config v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $select_path = 'Select'; + my $sel; + if ($sel = $root_key->get_subkey($select_path)) { + $current = $sel->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::rptMsg($select_path." could not be found."); + ::logMsg($select_path." could not be found."); + return; + } + + my @profiles = ("DomainProfile","StandardProfile"); + foreach my $profile (@profiles) { + my $key_path = $ccs."\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\".$profile; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Windows Firewall Configuration"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my %vals = getKeyValues($key); + if (scalar(keys %vals) > 0) { + foreach my $v (keys %vals) { + ::rptMsg("\t".$v." -> ".$vals{$v}); + } + } + else { +# ::rptMsg($key_path." has no values."); + } + + my @configs = ("RemoteAdminSettings", + "IcmpSettings", + "GloballyOpenPorts\\List", + "AuthorizedApplications\\List"); + + foreach my $config (@configs) { + eval { + my %vals = getKeyValues($key->get_subkey($config)); + if (scalar(keys %vals) > 0) { + ::rptMsg(""); + ::rptMsg($key_path."\\".$config); + ::rptMsg("LastWrite Time ".gmtime($key->get_subkey($config)->get_timestamp())." (UTC)"); + foreach my $v (keys %vals) { + ::rptMsg("\t".$v." -> ".$vals{$v}); + } + } + }; + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + ::rptMsg(""); + } # end foreach +} + +sub getKeyValues { + my $key = shift; + my %vals; + + my @vk = $key->get_list_of_values(); + if (scalar(@vk) > 0) { + foreach my $v (@vk) { + next if ($v->get_name() eq "" && $v->get_data() eq ""); + $vals{$v->get_name()} = $v->get_data(); + } + } + else { + + } + return %vals; +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/gthist.pl b/thirdparty/rr/plugins/gthist.pl new file mode 100644 index 0000000000000000000000000000000000000000..bc52f909a9706728355784d4337cac5c29ef6682 --- /dev/null +++ b/thirdparty/rr/plugins/gthist.pl @@ -0,0 +1,71 @@ +#----------------------------------------------------------- +# gthist.pl +# Google Toolbar Search History plugin +# +# +# Change history +# 20100218 - created +# +# References +# +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package gthist; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100218); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Google Toolbar Search History"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + my %hist; + ::logMsg("Launching gthist v.".$VERSION); + + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Google\\NavClient\\1.1\\History'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar @vals > 0) { + ::rptMsg(""); + foreach my $v (@vals) { + my $tv = unpack("V",$v->get_data()); + $hist{$tv} = $v->get_name(); + } + + foreach my $t (reverse sort {$a <=> $b} keys %hist) { + my $str = gmtime($t)." ".$hist{$t}; + ::rptMsg($str); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/gtwhitelist.pl b/thirdparty/rr/plugins/gtwhitelist.pl new file mode 100644 index 0000000000000000000000000000000000000000..e8d0695eea2ae03379d37905071b1b175271ee1a --- /dev/null +++ b/thirdparty/rr/plugins/gtwhitelist.pl @@ -0,0 +1,74 @@ +#----------------------------------------------------------- +# gtwhitelist.pl +# Google Toolbar Search History plugin +# +# +# Change history +# 20100218 - created +# +# References +# +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package gtwhitelist; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100218); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Google Toolbar whitelist values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + my %hist; + ::logMsg("Launching gtwhitelist v.".$VERSION); + + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Google\\Google Toolbar\\4.0\\whitelist'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my $allow2; + eval { + $allow2 = $key->get_value("allow2")->get_data(); + my @vals = split(/\|/,$allow2); + ::rptMsg(""); + ::rptMsg("whitelist"); + foreach my $v (@vals) { + next if ($v eq ""); + ::rptMsg(" ".$v); + } + ::rptMsg(""); + }; + + my $lastmod; + eval { + $lastmod = $key->get_value("lastmod")->get_data(); + ::rptMsg("lastmod ".gmtime($lastmod)." (UTC)"); + }; + + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/hibernate.pl b/thirdparty/rr/plugins/hibernate.pl new file mode 100644 index 0000000000000000000000000000000000000000..64c5b3e359fe62ac1fbd9c7a1f64298543c5115b --- /dev/null +++ b/thirdparty/rr/plugins/hibernate.pl @@ -0,0 +1,78 @@ +#----------------------------------------------------------- +# hibernate.pl +# +# Ref: +# http://support.microsoft.com/kb/293399 & testing +# +# copyright 2008-2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package hibernate; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081216); + +sub getConfig{return %config} + +sub getShortDescr { + return "Check hibernation status"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching hibernate v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + + my $power_path = $ccs."\\Control\\Session Manager\\Power"; + my $power; + if ($power = $root_key->get_subkey($power_path)) { + + my $heur; + eval { + my $bin_val = $power->get_value("Heuristics")->get_data(); + $heur = (unpack("v*",$bin_val))[3]; + if ($heur == 0) { + ::rptMsg("Hibernation disabled."); + } + elsif ($heur == 1) { + ::rptMsg("Hibernation enabled."); + } + else { + ::rptMsg("Unknown hibernation value: ".$heur); + } + + }; + ::rptMsg("Error reading Heuristics value.") if ($@); + + } + else { + ::rptMsg($power_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); +# ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ide.pl b/thirdparty/rr/plugins/ide.pl new file mode 100644 index 0000000000000000000000000000000000000000..789cbd14958fef76beeb7826318b320126c354b8 --- /dev/null +++ b/thirdparty/rr/plugins/ide.pl @@ -0,0 +1,123 @@ +#----------------------------------------------------------- +# ide.pl +# Get IDE device info from the System hive file +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package ide; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080418); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get IDE device info from the System hive file"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching ide v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + ::rptMsg("IDE"); + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::logMsg("Could not find ".$key_path); + return + } + + my $key_path = $ccs."\\Enum\\IDE"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg(""); + ::rptMsg($s->get_name()." [".gmtime($s->get_timestamp())."]"); + my @sk = $s->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s2 (@sk) { + ::rptMsg($s2->get_name()." [".gmtime($s2->get_timestamp())." (UTC)]"); + eval { + ::rptMsg("FriendlyName : ".$s2->get_value("FriendlyName")->get_data()); + }; + ::rptMsg(""); + } + } + + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + + my $key_path = $ccs."\\Control\\DeviceClasses\\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("DevClasses - Disks"); + ::rptMsg($key_path); + my %disks; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + next unless (grep(/IDE/,$name)); + my $lastwrite = $s->get_timestamp(); + my ($dev, $serial) = (split(/#/,$name))[4,5]; + push(@{$disks{$lastwrite}},$dev.",".$serial); + } + + if (scalar(keys %disks) == 0) { + ::rptMsg("No IDE subkeys were found."); + return; + } + ::rptMsg(""); + foreach my $t (reverse sort {$a <=> $b} keys %disks) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$disks{$t}}) { + ::rptMsg("\t$item"); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ie_main.pl b/thirdparty/rr/plugins/ie_main.pl new file mode 100644 index 0000000000000000000000000000000000000000..aa48c4d4a3f7c6ec604e781f677bce449c3ba80b --- /dev/null +++ b/thirdparty/rr/plugins/ie_main.pl @@ -0,0 +1,82 @@ +#----------------------------------------------------------- +# ie_main.pl +# Checks keys/values set by new version of Trojan.Clampi +# +# Change history +# 20091019 - created +# +# +# References +# http://support.microsoft.com/kb/895339 +# http://support.microsoft.com/kb/176497 +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package ie_main; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20091019); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets values beneath user's Internet Explorer\\Main key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching ie_main v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Internet Explorer\\Main'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my %main; + + my @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + next if ($name eq "Window_Placement"); + + $data = unpack("V",$data) if ($name eq "Do404Search"); + + if ($name eq "IE8RunOnceLastShown_TIMESTAMP" || $name eq "IE8TourShownTime") { + my ($t0,$t1) = unpack("VV",$data); + $data = gmtime(::getTime($t0,$t1))." UTC"; + } + $main{$name} = $data; + } + + foreach my $n (keys %main) { + my $str = sprintf "%-35s %-20s",$n,$main{$n}; + ::rptMsg($str); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ie_settings.pl b/thirdparty/rr/plugins/ie_settings.pl new file mode 100644 index 0000000000000000000000000000000000000000..fd3ee3857e8e37a5645677b2e26e86b2ac4403d1 --- /dev/null +++ b/thirdparty/rr/plugins/ie_settings.pl @@ -0,0 +1,72 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# ie_settings.pl +# Gets IE settings +# +# Change history +# +# +# References +# +# +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package ie_settings; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + osmask => 22, + version => 20091016); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets IE settings"; +} +sub getDescr{} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching ie_settings v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my $ua; + eval { + $ua = $key->get_value("User Agent")->get_data(); + ::rptMsg("User Agent = ".$ua); + }; + + my $zonessecupgrade; + eval { + $zonessecupgrade = $key->get_value("ZonesSecurityUpgrade")->get_data(); + my ($z0,$z1) = unpack("VV",$zonessecupgrade); + ::rptMsg("ZonesSecurityUpgrade = ".gmtime(::getTime($z0,$z1))." (UTC)"); + }; + + my $daystokeep; + eval { + $daystokeep = $key->get_subkey("Url History")->get_value("DaysToKeep")->get_data(); + ::rptMsg("DaysToKeep = ".$daystokeep); + }; + + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ie_version.pl b/thirdparty/rr/plugins/ie_version.pl new file mode 100644 index 0000000000000000000000000000000000000000..64ce73b0465b04b0b0cac641d69a817efc261ff2 --- /dev/null +++ b/thirdparty/rr/plugins/ie_version.pl @@ -0,0 +1,60 @@ +#----------------------------------------------------------- +# ie_version +# Get IE version and build +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package ie_version; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20091016); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get IE version and build"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching ie_version v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Internet Explorer"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $version; + my $build; + eval { + $build = $key->get_value("Build")->get_data(); + ::rptMsg("IE Build = ".$build); + }; + + eval { + $version= $key->get_value("Version")->get_data(); + ::rptMsg("IE Version = ".$version); + }; + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/imagedev.pl b/thirdparty/rr/plugins/imagedev.pl new file mode 100644 index 0000000000000000000000000000000000000000..5822ae7a158c4ec756bdc720ca0c02cd63b52475 --- /dev/null +++ b/thirdparty/rr/plugins/imagedev.pl @@ -0,0 +1,85 @@ +#----------------------------------------------------------- +# imagedev.pl +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package imagedev; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080730); + +sub getConfig{return %config} + +sub getShortDescr { + return " -- "; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching imagedev v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + eval { + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + }; + if ($@) { + ::rptMsg("Problem locating proper controlset: $@"); + return; + } + + my $key_path = $ccs."\\Control\\Class\\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("imagedev"); + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @sk = $key->get_list_of_subkeys(); + + if (scalar(@sk) > 0) { + ::rptMsg("Still Image Capture Devices"); + foreach my $s (@sk) { + my $name = $s->get_name(); + next unless ($name =~ m/^\d{4}$/); + my $friendly; + eval { + $friendly = $s->get_value("FriendlyName")->get_data(); + ::rptMsg(" ".$friendly); + }; + if ($@) { + ::logMsg("Error getting device FriendlyName in imagedev: ".$@); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/imagefile.pl b/thirdparty/rr/plugins/imagefile.pl new file mode 100644 index 0000000000000000000000000000000000000000..1f31f674b7bb9137f712ab66d9142d0905f57f5c --- /dev/null +++ b/thirdparty/rr/plugins/imagefile.pl @@ -0,0 +1,99 @@ +#----------------------------------------------------------- +# imagefile +# +# References: +# http://msdn2.microsoft.com/en-us/library/a329t4ed(VS\.80)\.aspx +# http://support.microsoft.com/kb/2264107 +# +# Change history: +# 20100824 - added check for "CWDIllegalInDllSearch" value +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package imagefile; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100824); + +sub getConfig{return %config} +sub getShortDescr { + return "Checks IFEO subkeys for Debugger/CWDIllegalInDllSearch values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching imagefile v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Image File Execution Options"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + my %debug; + my $i = "Your Image File Name here without a path"; + foreach my $s (@subkeys) { + my $name = $s->get_name(); + next if ($name =~ m/^$i/i); + my $debugger = ""; + eval { + $debugger = $s->get_value("Debugger")->get_data(); + }; +# If the eval{} throws an error, it's b/c the Debugger value isn't +# found within the key, so we don't need to do anything w/ the error + if ($debugger ne "") { + $debug{$name}{debug} = $debugger; + $debug{$name}{lastwrite} = $s->get_timestamp(); + } + + my $dllsearch = ""; + eval { + $dllsearch = $s->get_value("CWDIllegalInDllSearch")->get_data(); + }; +# If the eval{} throws an error, it's b/c the Debugger value isn't +# found within the key, so we don't need to do anything w/ the error + if ($dllsearch ne "") { + $debug{$name}{dllsearch} = $debugger; + $debug{$name}{lastwrite} = $s->get_timestamp(); + } + } + + if (scalar (keys %debug) > 0) { + foreach my $d (keys %debug) { + ::rptMsg($d." LastWrite: ".gmtime($debug{$d}{lastwrite})); + ::rptMsg(" Debugger : ".$debug{$d}{debug}) if (exists $debug{$d}{debug}); + ::rptMsg(" CWDIllegalInDllSearch: ".$debug{$d}{dllsearch}) if (exists $debug{$d}{dllsearch}); + } + } + else { + ::rptMsg("No Debugger/CWDIllegalInDllSearch values found."); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys"); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/init_dlls.pl b/thirdparty/rr/plugins/init_dlls.pl new file mode 100644 index 0000000000000000000000000000000000000000..d729a6b7166fbb6a169d0c90f6b63ad59e89af67 --- /dev/null +++ b/thirdparty/rr/plugins/init_dlls.pl @@ -0,0 +1,77 @@ +#----------------------------------------------------------- +# init_dlls.pl +# Plugin to assist in the detection of malware per Mark Russinovich's +# blog post (References, below) +# +# Change History: +# 20110309 - created +# +# References +# http://blogs.technet.com/b/markrussinovich/archive/2011/02/27/3390475.aspx +# +# copyright 2011 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package init_dlls; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20110309); + +sub getConfig{return %config} + +sub getShortDescr { + return "Check for odd **pInit_Dlls keys"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my @init; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching init_dlls v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Windows"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("init_dlls"); + ::rptMsg($key_path); + ::rptMsg("LastWrite: ".gmtime($key->get_timestamp())); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + next if ($name eq "AppInit_DLLs"); + push(@init,$name) if ($name =~ m/Init_DLLs$/); + } + + if (scalar @init > 0) { + foreach my $n (@init) { + ::rptMsg($n); + } + } + else { + ::rptMsg("No additional values named *Init_DLLs located."); + } + + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/installedcomp.pl b/thirdparty/rr/plugins/installedcomp.pl new file mode 100644 index 0000000000000000000000000000000000000000..9fd730301fa119789425912f08bdc6e7676799a3 --- /dev/null +++ b/thirdparty/rr/plugins/installedcomp.pl @@ -0,0 +1,120 @@ +#----------------------------------------------------------- +# installedcomp.pl +# Get info about Installed Components +# +# Change history: +# 20100116 - updated for slightly better coverage +# 20100115 - created +# +# References: +# +# Notes: Look for out of place entries, particularly those +# that point to the Recycle Bin or a temp directory +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package installedcomp; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100116); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get info about Installed Components/StubPath"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %comp; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching installedcomp v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Active Setup\\Installed Components"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $lastwrite = $s->get_timestamp(); + + my $str; + eval { + $str = $s->get_value("ComponentID")->get_data(); + }; + + eval { + my $ver = $s->get_value("Version")->get_data(); + $str .= " v.".$ver if ($ver && $s->get_value("Version")->get_type() == 1); + }; + + eval { + my $stub = $s->get_value("StubPath")->get_data(); + $str .= "; ".$stub if ($stub ne ""); + }; + +# If the $str scalar is empty at this point, that means that for +# some reason, we haven't been able to populate the information +# we're looking for; in this case, we'll go looking for some info +# in a different area of the hive; the BHO.pl plugin does this, as +# well. I'd rather that the plugin look for the Classes info than +# leave a blank entry in the output. + if ($str eq "") { + my $name = $s->get_name(); + my $class_path = "Classes\\CLSID\\".$name; + my $proc; + if ($proc = $root_key->get_subkey($class_path)) { +# Try these two eval{} statements because I've seen the different +# spellings for InProcServer32/InprocServer32 in sequential keys + eval { + $str = $proc->get_subkey("InprocServer32")->get_value("")->get_data(); + }; + + eval { + $str = $proc->get_subkey("InProcServer32")->get_value("")->get_data(); + }; + } + else { + $str = $name." class not found."; + } + } + + push(@{$comp{$lastwrite}},$str); + } + + foreach my $t (reverse sort {$a <=> $b} keys %comp) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$comp{$t}}) { + ::rptMsg(" ".$item); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/javafx.pl b/thirdparty/rr/plugins/javafx.pl new file mode 100644 index 0000000000000000000000000000000000000000..118e82cb5866815eccbfa6b4a419b1ef3ce620b9 --- /dev/null +++ b/thirdparty/rr/plugins/javafx.pl @@ -0,0 +1,67 @@ +#----------------------------------------------------------- +# javafx.pl +# Plugin written based on Cory Harrell's Exploit Artifacts posts at +# http://journeyintoir.blogspot.com/ +# +# Change history +# 20110322 - created +# +# References +# http://java.sun.com/j2se/1.4.2/runtime_win32.html +# +# copyright 2011 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package javafx; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20110322); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's JavaFX key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching javafx v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\JavaSoft\\Java Update\\Policy\\JavaFX"; + my $key; + my @vals; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("javafx v.".$VERSION); + ::rptMsg($key_path); + ::rptMsg("LastWrite time: ".gmtime($key->get_timestamp())); + ::rptMsg(""); + @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { +# First, read in all of the values and the data + foreach my $v (@vals) { + ::rptMsg(sprintf "%-25s %-20s",$v->get_name(), $v->get_data()); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/kb950582.pl b/thirdparty/rr/plugins/kb950582.pl new file mode 100644 index 0000000000000000000000000000000000000000..4e24fe3dd2e839343480378ad9b279c46675bc70 --- /dev/null +++ b/thirdparty/rr/plugins/kb950582.pl @@ -0,0 +1,90 @@ +#----------------------------------------------------------- +# kb950582.pl +# Get autorun settings WRT KB950582 +# +# Change history +# 18 Dec 2008 - Updated to new name; added checks for Registry +# keys +# +# References +# http://support.microsoft.com/kb/953252 +# http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit +# /regentry/91525.mspx?mfr=true +# +# copyright 2008-2009 H. Carvey +#----------------------------------------------------------- +package kb950582; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081212); + +sub getConfig{return %config} +sub getShortDescr { + return "KB950582 - Gets autorun settings from HKLM hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching kb950582 v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + eval { + my $path = "Microsoft\\Windows\\CurrentVersion\\Uninstall\\KB950582"; + if (my $kbkey = $root_key->get_subkey($path)) { + my $install = $kbkey->get_value("InstallDate")->get_data(); + ::rptMsg("KB950528 Uninstall Key ".gmtime($kbkey->get_timestamp())); + ::rptMsg(" InstallDate = ".$install."\n"); + } + }; + ::rptMsg("Uninstall\\KB950528 does not appear to be installed.\n") if ($@); + + eval { + my $path = "Microsoft\\Updates\\Windows XP\\SP4\\KB950582"; + if (my $kbkey = $root_key->get_subkey($path)) { + my $install = $kbkey->get_value("InstalledDate")->get_data(); + ::rptMsg("KB950528 Update Key ".gmtime($kbkey->get_timestamp())); + ::rptMsg(" InstalledDate = ".$install."\n"); + } + }; + ::rptMsg("KB950528 does not appear to be installed.\n") if ($@); + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + + eval { + my $nodrive = $key->get_value("NoDriveTypeAutoRun")->get_data(); + my $str = sprintf "%-20s 0x%x","NoDriveTypeAutoRun",$nodrive; + ::rptMsg($str); + }; + ::rptMsg("Error: ".$@) if ($@); + +# http://support.microsoft.com/kb/953252 + eval { + my $honor = $key->get_value("HonorAutorunSetting")->get_data(); + my $str = sprintf "%-20s 0x%x","HonorAutorunSetting",$honor; + ::rptMsg($str); + }; + ::rptMsg("HonorAutorunSetting not found.") if ($@); + ::rptMsg(""); + ::rptMsg("Autorun settings in the HKLM hive take precedence over those in"); + ::rptMsg("the HKCU hive."); + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/kbdcrash.pl b/thirdparty/rr/plugins/kbdcrash.pl new file mode 100644 index 0000000000000000000000000000000000000000..560aef97859c6b87a90d39684f5933aeaa60282d --- /dev/null +++ b/thirdparty/rr/plugins/kbdcrash.pl @@ -0,0 +1,65 @@ +#----------------------------------------------------------- +# kbdcrash.pl +# +# Ref: +# http://support.microsoft.com/kb/244139 +# +# copyright 2008-2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package kbdcrash; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081212); + +sub getConfig{return %config} + +sub getShortDescr { + return "Checks to see if system is config to crash via keyboard"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $enabled = 0; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching kbdcrash v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $svc = "ControlSet00".$current."\\Services"; + + eval { + my $ps2 = $svc->get_subkey("i8042prt\\Parameters")->get_value("CrashOnCtrlScroll")->get_data(); + ::rptMsg("CrashOnCtrlScroll set for PS2 keyboard") if ($ps2 == 1); + $enabled = 1 if ($ps2 == 1); + }; + + eval { + my $usb = $svc->get_subkey("kbdhid\\Parameters")->get_value("CrashOnCtrlScroll")->get_data(); + ::rptMsg("CrashOnCtrlScroll set for USB keyboard") if ($usb == 1); + $enabled = 1 if ($usb == 1); + }; + ::rptMsg("CrashOnCtrlScroll not set"); + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; diff --git a/thirdparty/rr/plugins/landesk.pl b/thirdparty/rr/plugins/landesk.pl new file mode 100644 index 0000000000000000000000000000000000000000..d3dd8c532091a59ded039f1e387b8a82d945cb0d --- /dev/null +++ b/thirdparty/rr/plugins/landesk.pl @@ -0,0 +1,71 @@ +#----------------------------------------------------------- +# LANDESK Monitor Logs +# +# +# Change history +# 20090729 - updates, H. Carvey +# +# copyright 2009 Don C. Weber +#----------------------------------------------------------- +package landesk; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090729); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get list of programs monitored by LANDESK from Software hive file"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my %ls; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching LANDESK v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "LANDesk\\ManagementSuite\\WinClient\\SoftwareMonitoring\\MonitorLog"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + eval { + my ($val1,$val2) = unpack("VV",$s->get_value("Last Started")->get_data()); +# Push the data into a hash of arrays + push(@{$ls{::getTime($val1,$val2)}},$s->get_name()); + }; + } + + foreach my $t (reverse sort {$a <=> $b} keys %ls) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$ls{$t}}) { + ::rptMsg("\t$item"); + } + } + } + else { + ::rptMsg($key_path." does not appear to have any subkeys.") + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/legacy.pl b/thirdparty/rr/plugins/legacy.pl new file mode 100644 index 0000000000000000000000000000000000000000..3c34a1a26ae468711d6852d411ceda519c69b6e5 --- /dev/null +++ b/thirdparty/rr/plugins/legacy.pl @@ -0,0 +1,96 @@ +#----------------------------------------------------------- +# legacy.pl +# +# +# Change history +# 20090429 - created +# +# Reference: http://support.microsoft.com/kb/310592 +# +# +# Analysis Tip: +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package legacy; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090429); + +sub getConfig{return %config} +sub getShortDescr { + return "Lists LEGACY_ entries in Enum\\Root key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key(); +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $root_path = $ccs."\\Enum\\Root"; + + my %legacy; + if (my $root = $root_key->get_subkey($root_path)) { + my @sk = $root->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + my $name = $s->get_name(); + next unless ($name =~ m/^LEGACY_/); + push(@{$legacy{$s->get_timestamp()}},$name); + + eval { + my @s_sk = $s->get_list_of_subkeys(); + if (scalar(@s_sk) > 0) { + foreach my $s_s (@s_sk) { + + my $desc; + eval { + $desc = $s_s->get_value("DeviceDesc")->get_data(); + push(@{$legacy{$s_s->get_timestamp()}},$name."\\".$s_s->get_name()." - ".$desc); + }; + push(@{$legacy{$s_s->get_timestamp()}},$name."\\".$s_s->get_name()) if ($@); + } + } + }; + } + } + else { + ::rptMsg($root_path." has no subkeys."); + } + + foreach my $t (reverse sort {$a <=> $b} keys %legacy) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$legacy{$t}}) { + ::rptMsg("\t$item"); + } + } + } + else { + ::rptMsg($root_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/listsoft.pl b/thirdparty/rr/plugins/listsoft.pl new file mode 100644 index 0000000000000000000000000000000000000000..ae1c50a540192854446fbbc9d2d4448a9a58e025 --- /dev/null +++ b/thirdparty/rr/plugins/listsoft.pl @@ -0,0 +1,69 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# listsoft.pl +# Plugin for Registry Ripper; traverses thru the Software +# key of an NTUSER.DAT file, extracting all of the subkeys +# and listing them in order by LastWrite time. +# +# Change history +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package listsoft; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Lists contents of user's Software key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $file = shift; + my $reg = Parse::Win32Registry->new($file); + my $root_key = $reg->get_root_key; + ::logMsg("Launching listsoft v.".$VERSION); + my %soft; + my $key_path = 'Software'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("listsoft v.".$VERSION); + ::rptMsg("List the contents of the Software key in the NTUSER\.DAT hive"); + ::rptMsg("file, in order by LastWrite time."); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + push(@{$soft{$s->get_timestamp()}},$s->get_name()); + } + + foreach my $t (reverse sort {$a <=> $b} keys %soft) { + foreach my $item (@{$soft{$t}}) { + ::rptMsg(gmtime($t)."Z \t".$item); + } + } + } + else { + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::logMsg("Could not access ".$key_path); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/load.pl b/thirdparty/rr/plugins/load.pl new file mode 100644 index 0000000000000000000000000000000000000000..3ce6ca655e5147428d4d3b5bbd62543ef5728468 --- /dev/null +++ b/thirdparty/rr/plugins/load.pl @@ -0,0 +1,81 @@ +#----------------------------------------------------------- +# load.pl +# The load and run values in the Windows NT\CurrentVersion\Windows +# key are throw-backs to the old win.ini file, and can be/are used +# by malware. +# +# Change history +# 20100811 - created +# +# References +# http://support.microsoft.com/kb/103865 +# http://security.fnal.gov/cookbook/WinStartup.html +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package load; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100811); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets load and run values from user hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching load v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("load"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + ::rptMsg(""); + my %win; + foreach my $v (@vals) { + $win{$v->get_name()} = $v->get_data(); + } + + if (exists $win{"load"}) { + ::rptMsg("load = ".$win{"load"}); + } + else { + ::rptMsg("load value not found."); + } + + if (exists $win{"run"}) { + ::rptMsg("run = ".$win{"run"}); + } + else { + ::rptMsg("run value not found."); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/logon_xp_run.pl b/thirdparty/rr/plugins/logon_xp_run.pl new file mode 100644 index 0000000000000000000000000000000000000000..831a5cd910be0da9a921aa30c65cd86cabe27534 --- /dev/null +++ b/thirdparty/rr/plugins/logon_xp_run.pl @@ -0,0 +1,98 @@ +#----------------------------------------------------------- +# logon_xp_run +# Get contents of Run key from Software hive +# +# References: +# http://support.microsoft.com/kb/314488 +# +# Note: Needs testing to see if it applies beyond XP/XP-64 +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package logon_xp_run; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 12, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080328); + +sub getConfig{return %config} + +sub getShortDescr { + return "Autostart - Get XP user logon Run key contents from NTUSER\.DAT hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching user_xp_run v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies\\Explorer\\Run"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my %vals = getKeyValues($key); + if (scalar(keys %vals) > 0) { + foreach my $v (keys %vals) { + ::rptMsg("\t".$v." -> ".$vals{$v}); + } + } + else { + ::rptMsg($key_path." has no values."); + } + +# my @sk = $key->get_list_of_subkeys(); +# if (scalar(@sk) > 0) { +# foreach my $s (@sk) { +# ::rptMsg(""); +# ::rptMsg($key_path."\\".$s->get_name()); +# ::rptMsg("LastWrite Time ".gmtime($s->get_timestamp())." (UTC)"); +# my %vals = getKeyValues($s); +# foreach my $v (keys %vals) { +# ::rptMsg("\t".$v." -> ".$vals{$v}); +# } +# } +# } +# else { +# ::rptMsg(""); +# ::rptMsg($key_path." has no subkeys."); +# } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} + +sub getKeyValues { + my $key = shift; + my %vals; + + my @vk = $key->get_list_of_values(); + if (scalar(@vk) > 0) { + foreach my $v (@vk) { + next if ($v->get_name() eq "" && $v->get_data() eq ""); + $vals{$v->get_name()} = $v->get_data(); + } + } + else { +# do nothing + } + return %vals; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/logonusername.pl b/thirdparty/rr/plugins/logonusername.pl new file mode 100644 index 0000000000000000000000000000000000000000..098d89f5e651142169accb6aff6efc043a3f6312 --- /dev/null +++ b/thirdparty/rr/plugins/logonusername.pl @@ -0,0 +1,68 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# logonusername.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# "Logon User Name" value +# +# Change history +# +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package logonusername; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Get user's Logon User Name value"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching logonusername v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $logon_name = "Logon User Name"; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + ::rptMsg("Logon User Name"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time [".gmtime($key->get_timestamp())." (UTC)]"); + foreach my $v (@vals) { + if ($v->get_name() eq $logon_name) { + ::rptMsg($logon_name." = ".$v->get_data()); + } + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/lsasecrets.pl b/thirdparty/rr/plugins/lsasecrets.pl new file mode 100644 index 0000000000000000000000000000000000000000..1e0048e973afcb781011cf3bf5e8bcf57be34527 --- /dev/null +++ b/thirdparty/rr/plugins/lsasecrets.pl @@ -0,0 +1,71 @@ +#----------------------------------------------------------- +# lsasecrets.pl +# Get update times for LSA Secrets from the Security hive file +# +# History +# 20100219 - created +# +# References +# http://moyix.blogspot.com/2008/02/decrypting-lsa-secrets.html +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package lsasecrets; +use strict; + +my %config = (hive => "Security", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100219); + +sub getConfig{return %config} +sub getShortDescr { + return "TEST - Get update times for LSA Secrets"; +} +sub getDescr{} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching lsasecrets v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Policy\\Secrets"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + +# +# http://support.microsoft.com/kb/175468 + eval { + ::rptMsg(""); + ::rptMsg("Domain secret - \$MACHINE\.ACC"); + my $c = $key->get_subkey("\$MACHINE\.ACC\\CupdTime")->get_value("")->get_data(); + my @v = unpack("VV",$c); + my $cupd = gmtime(::getTime($v[0],$v[1])); + ::rptMsg("CupdTime = ".$cupd); + + my $o = $key->get_subkey("\$MACHINE\.ACC\\OupdTime")->get_value("")->get_data(); + my @v = unpack("VV",$c); + my $oupd = gmtime(::getTime($v[0],$v[1])); + ::rptMsg("OupdTime = ".$oupd); + }; + ::rptMsg("Error: ".$@) if ($@); + + + + + + + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/macaddr.pl b/thirdparty/rr/plugins/macaddr.pl new file mode 100644 index 0000000000000000000000000000000000000000..50a034981a0bc94d1880ccd331b973d3ac3a4826 --- /dev/null +++ b/thirdparty/rr/plugins/macaddr.pl @@ -0,0 +1,156 @@ +#----------------------------------------------------------- +# macaddr.pl +# Attempt to locate MAC address in either Software or System hive files; +# The plugin will determine which one its in and use the appropriate +# code +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package macaddr; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090118); + +sub getConfig{return %config} + +sub getShortDescr { + return " -- "; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching macaddr v.".$VERSION); + + my $guess = guessHive($hive); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + if ($guess eq "System") { +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + + my $key_path = $ccs."\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"; + my $key; + my $found = 0; + ::rptMsg($key_path); + if ($key = $root_key->get_subkey($key_path)) { + my @subkeys = $key->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + my $na; + eval { + $na = $key->get_subkey($name)->get_value("NetworkAddress")->get_data(); + ::rptMsg(" ".$name.": NetworkAddress = ".$na); + $found = 1; + }; + } + ::rptMsg("No NetworkAddress value found.") if ($found == 0); + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } + } + elsif ($guess eq "Software") { + my $key_path = "Microsoft\\Windows Genuine Advantage"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my $mac; + my $found = 0; + eval { + $mac = $key->get_value("MAC")->get_data(); + ::rptMsg("Mac Address(es) = ".$mac); + $found = 1; + }; + ::rptMsg("No MAC address(es) found.") if ($found == 0); + } + else { + ::rptMsg($key_path." not found."); + } + } + else { + ::rptMsg("Hive file ".$hive." appeared to be neither a Software nor a"); + ::rptMsg("System hive file."); + } +} + +#------------------------------------------------------------- +# guessHive() - attempts to determine the hive type; if NTUSER.DAT, +# attempt to retrieve the SID for the user; this function populates +# global variables (%config, @sids) +#------------------------------------------------------------- +sub guessHive { + my $hive = shift; + my $hive_guess; + my $reg; + my $root_key; + eval { + $reg = Parse::Win32Registry->new($hive); + $root_key = $reg->get_root_key; + }; + ::rptMsg($hive." may not be a valid hive.") if ($@); + +# Check for SAM + eval { + if (my $key = $root_key->get_subkey("SAM\\Domains\\Account\\Users")) { + $hive_guess = "SAM"; + } + }; +# Check for Software + eval { + if ($root_key->get_subkey("Microsoft\\Windows\\CurrentVersion") && + $root_key->get_subkey("Microsoft\\Windows NT\\CurrentVersion")) { + $hive_guess = "Software"; + } + }; + +# Check for System + eval { + if ($root_key->get_subkey("MountedDevices") && $root_key->get_subkey("Select")) { + $hive_guess = "System"; + } + }; + +# Check for Security + eval { + if ($root_key->get_subkey("Policy\\Accounts") && $root_key->get_subkey("Policy\\PolAdtEv")) { + $hive_guess = "Security"; + } + }; +# Check for NTUSER.DAT + eval { + if ($root_key->get_subkey("Software\\Microsoft\\Windows\\CurrentVersion")) { + $hive_guess = "NTUSER\.DAT"; + } + }; + return $hive_guess; +} + + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mmc.pl b/thirdparty/rr/plugins/mmc.pl new file mode 100644 index 0000000000000000000000000000000000000000..d66557c5da47e25176695e7a8e35d8b85069f9bc --- /dev/null +++ b/thirdparty/rr/plugins/mmc.pl @@ -0,0 +1,75 @@ +#----------------------------------------------------------- +# mmc.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# Microsoft Management Console Recent File List values +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package mmc; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Get contents of user's MMC\\Recent File List key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching mmc v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Microsoft Management Console\\Recent File List'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("MMC - Recent File List"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %files; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/File/,$val))[1]; + $files{$tag} = $val.":".$data; + } +# Print sorted content to report file + foreach my $u (sort {$a <=> $b} keys %files) { + my ($val,$data) = split(/:/,$files{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mndmru.pl b/thirdparty/rr/plugins/mndmru.pl new file mode 100644 index 0000000000000000000000000000000000000000..d223d7f49c873eb28fcd42f7b91b812d90b1e30f --- /dev/null +++ b/thirdparty/rr/plugins/mndmru.pl @@ -0,0 +1,77 @@ +#----------------------------------------------------------- +# mndmru.pl +# Plugin for Registry Ripper, +# Map Network Drive MRU parser +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package mndmru; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Get contents of user's Map Network Drive MRU"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching mndmru v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Map Network Drive MRU'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Map Network Drive MRU"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %mnd; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + $mnd{$val} = $data; + } +# Print sorted content to report file + if (exists $mnd{"MRUList"}) { + ::rptMsg(" MRUList = ".$mnd{"MRUList"}); + delete $mnd{"MRUList"}; + } + foreach my $m (sort {$a <=> $b} keys %mnd) { + ::rptMsg(" ".$m." ".$mnd{$m}); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mountdev.pl b/thirdparty/rr/plugins/mountdev.pl new file mode 100644 index 0000000000000000000000000000000000000000..ae0d58b26b1291347632c52e8ac7ec406c0a9c45 --- /dev/null +++ b/thirdparty/rr/plugins/mountdev.pl @@ -0,0 +1,101 @@ +#----------------------------------------------------------- +# mountdev.pl +# Plugin for Registry Ripper; Access System hive file to get the +# MountedDevices +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package mountdev; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Return contents of System hive MountedDevices key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching mountdev v.".$VERSION); + ::rptMsg("mountdev v.".$VERSION); + ::rptMsg("Get MountedDevices key information from the System hive file."); + ::rptMsg(""); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = 'MountedDevices'; + my $key; + my %md; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite time = ".gmtime($key->get_timestamp())."Z"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $data = $v->get_data(); + my $len = length($data); + if ($len == 12) { + my $sig = _translateBinary(substr($data,0,4)); + ::rptMsg($v->get_name()); + ::rptMsg("\tDrive Signature = ".$sig); + } + elsif ($len > 12) { + $data =~ s/\00//g; + push(@{$md{$data}},$v->get_name()); + } + else { + ::logMsg("mountdev v.".$VERSION."\tData length = $len"); + } + } + + ::rptMsg(""); + foreach my $m (keys %md) { + ::rptMsg("Device: ".$m); + foreach my $item (@{$md{$m}}) { + ::rptMsg("\t".$item); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +sub _translateBinary { + my $str = unpack("H*",$_[0]); + my $len = length($str); + my @nstr = split(//,$str,$len); + my @list = (); + foreach (0..($len/2)) { + push(@list,$nstr[$_*2].$nstr[($_*2)+1]); + } + return join(' ',@list); +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mountdev2.pl b/thirdparty/rr/plugins/mountdev2.pl new file mode 100644 index 0000000000000000000000000000000000000000..d5b1c3e324107cb2b9f65b47bb80f4fa4fcd6330 --- /dev/null +++ b/thirdparty/rr/plugins/mountdev2.pl @@ -0,0 +1,106 @@ +#----------------------------------------------------------- +# mountdev2.pl +# Plugin for Registry Ripper; Access System hive file to get the +# MountedDevices +# +# Change history +# 20091116 - changed output +# +# References +# +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package mountdev2; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20091116); + +sub getConfig{return %config} +sub getShortDescr { + return "Return contents of System hive MountedDevices key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching mountdev2 v.".$VERSION); + ::rptMsg(""); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = 'MountedDevices'; + my $key; + my (%md,%dos,%vol); + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite time = ".gmtime($key->get_timestamp())."Z"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $data = $v->get_data(); + my $len = length($data); + if ($len == 12) { + my $sig = _translateBinary(substr($data,0,4)); +# my $sig = _translateBinary($data); + $vol{$v->get_name()} = $sig; + } + elsif ($len > 12) { + $data =~ s/\00//g; + push(@{$md{$data}},$v->get_name()); + } + else { + ::logMsg("mountdev2 v.".$VERSION."\tData length = $len"); + } + } + + ::rptMsg(sprintf "%-50s %-20s","Volume","Disk Sig"); + ::rptMsg(sprintf "%-50s %-20s","-------","--------"); + foreach my $v (sort keys %vol) { + my $str = sprintf "%-50s %-20s",$v,$vol{$v}; + ::rptMsg($str); + } + + ::rptMsg(""); + foreach my $m (sort keys %md) { + ::rptMsg("Device: ".$m); + foreach my $item (@{$md{$m}}) { + ::rptMsg("\t".$item); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +sub _translateBinary { + my $str = unpack("H*",$_[0]); + my $len = length($str); + my @nstr = split(//,$str,$len); + my @list = (); + foreach (0..($len/2)) { + push(@list,$nstr[$_*2].$nstr[($_*2)+1]); + } + return join(' ',@list); +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mountdev3.pl b/thirdparty/rr/plugins/mountdev3.pl new file mode 100644 index 0000000000000000000000000000000000000000..ff4d4cfbf04174bd2107a8d3a14d951e158a74eb --- /dev/null +++ b/thirdparty/rr/plugins/mountdev3.pl @@ -0,0 +1,110 @@ +#----------------------------------------------------------- +# mountdev3.pl +# Plugin for Registry Ripper; Access System hive file to get the +# MountedDevices +# +# Change history +# +# +# References +# +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package mountdev3; +use Math::BigInt; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090909); + +sub getConfig{return %config} +sub getShortDescr { + return "Return contents of System hive MountedDevices key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; +# ::logMsg("Launching mountdev3 v.".$VERSION); + ::rptMsg("mountdev3 v.".$VERSION); + ::rptMsg("Get MountedDevices key information from the System hive file."); + ::rptMsg(""); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = 'MountedDevices'; + my $key; + my %md; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite time = ".gmtime($key->get_timestamp())."Z"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $data = $v->get_data(); + my $len = length($data); + if ($len == 12) { + my $sig = _translateBinary(substr($data,0,4)); + my ($low,$high) = unpack("VV",substr($data,4,8)); + my $val64 = Math::BigInt->new($high)->blsft(32)->bxor($low); + my $driveoffset = ($val64/512); + ::rptMsg($v->get_name()); + ::rptMsg("\tDrive Signature = ".$sig); + ::rptMsg("\tPartition offset = ".$driveoffset); + } + elsif ($len == 16) { + ::rptMsg($v->get_name()); + ::rptMsg("\t".$data); + } + elsif ($len > 16) { + $data =~ s/\00//g; + push(@{$md{$data}},$v->get_name()); + } + else { + ::logMsg("mountdev v.".$VERSION."\tData length = $len"); + } + } + + ::rptMsg(""); + foreach my $m (keys %md) { + ::rptMsg("Device: ".$m); + foreach my $item (@{$md{$m}}) { + ::rptMsg("\t".$item); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +sub _translateBinary { + my $str = unpack("H*",$_[0]); + my $len = length($str); + my @nstr = split(//,$str,$len); + my @list = (); + foreach (0..($len/2)) { + push(@list,$nstr[$_*2].$nstr[($_*2)+1]); + } + return join(' ',@list); +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mp2.pl b/thirdparty/rr/plugins/mp2.pl new file mode 100644 index 0000000000000000000000000000000000000000..b7ef8f76d67337f76129c7498bd4ab541cbfb197 --- /dev/null +++ b/thirdparty/rr/plugins/mp2.pl @@ -0,0 +1,114 @@ +#----------------------------------------------------------- +# mp2.pl +# Plugin for Registry Ripper, +# MountPoints2 key parser +# +# Change history +# 20091116 - updated output/sorting; added getting +# _LabelFromReg value +# 20090115 - Removed printing of "volumes" +# +# References +# http://support.microsoft.com/kb/932463 +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package mp2; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090115); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets user's MountPoints2 key contents"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching mp2 v.".$VERSION); + + my %drives; + my %volumes; + my %remote; + + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MountPoints2'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("MountPoints2"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + if ($name =~ m/^{/) { + my $label; + eval { + $label = $s->get_value("_LabelFromReg")->get_data(); + }; + $name = $name." (".$label.")" unless ($@); + push(@{$volumes{$s->get_timestamp()}},$name); + } + elsif ($name =~ m/^[A-Z]/) { + push(@{$drives{$s->get_timestamp()}},$name); + } + elsif ($name =~ m/^#/) { + push(@{$remote{$s->get_timestamp()}},$name); + } + else { + ::rptMsg(" Key name = ".$name); + } + } + ::rptMsg(""); + ::rptMsg("Remote Drives:"); + foreach my $t (reverse sort {$a <=> $b} keys %remote) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$remote{$t}}) { + ::rptMsg(" $item"); + } + } + + ::rptMsg(""); + ::rptMsg("Volumes:"); + foreach my $t (reverse sort {$a <=> $b} keys %volumes) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$volumes{$t}}) { + ::rptMsg(" $item"); + } + } + ::rptMsg(""); + ::rptMsg("Drives:"); + foreach my $t (reverse sort {$a <=> $b} keys %drives) { + my $d = join(',',(@{$drives{$t}})); + ::rptMsg(gmtime($t)." (UTC) - ".$d); + } + + ::rptMsg(""); + ::rptMsg("Analysis Tip: Correlate the Volume entries to those found in the MountedDevices"); + ::rptMsg("entries that begin with \"\\??\\Volume\"\."); + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mpmru.pl b/thirdparty/rr/plugins/mpmru.pl new file mode 100644 index 0000000000000000000000000000000000000000..701f0a802d607d782f940b76c03913cdb51f1df1 --- /dev/null +++ b/thirdparty/rr/plugins/mpmru.pl @@ -0,0 +1,75 @@ +#----------------------------------------------------------- +# mpmru.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# Media Player RecentFileList values +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package mpmru; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets user's Media Player RecentFileList values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching mpmru v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\MediaPlayer\\Player\\RecentFileList'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Media Player - RecentFileList"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %files; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/File/,$val))[1]; + $files{$tag} = $val.":".$data; + } +# Print sorted content to report file + foreach my $u (sort {$a <=> $b} keys %files) { + my ($val,$data) = split(/:/,$files{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mrt.pl b/thirdparty/rr/plugins/mrt.pl new file mode 100644 index 0000000000000000000000000000000000000000..89e9ebddafb7f6e5b53676f3da536f124220fb60 --- /dev/null +++ b/thirdparty/rr/plugins/mrt.pl @@ -0,0 +1,72 @@ +#----------------------------------------------------------- +# mrt.pl +# +# Per http://support.microsoft.com/kb/891716/, whenever MRT is run, a new +# GUID is written to the Version value. Check the KB article to compare +# GUIDs against the last time the tool was run. Also be sure to check the +# MRT logs in %WinDir%\Debug (mrt.log) +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package mrt; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20080804); + +sub getConfig{return %config} + +sub getShortDescr { + return "Check to see if Malicious Software Removal Tool has been run"; +} +sub getDescr{} +sub getRefs {"Deployment of the Microsoft Windows Malicious Software Removal Tool" => + "http://support.microsoft.com/kb/891716/", + "The Microsoft Windows Malicious Software Removal Tool" => "http://support.microsoft.com/?kbid=890830"} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching MRT v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + + my $key_path = "Microsoft\\RemovalTools\\MRT"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Key Path: ".$key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $version; + eval { + $version = $key->get_value("Version")->get_data(); + }; + if ($@) { + ::rptMsg("Error getting Version information: ".$@); + + } + else { + ::rptMsg("Version: ".$version); + ::rptMsg(""); + ::rptMsg("Analysis Tip: Go to http://support.microsoft.com/kb/891716/ to see when MRT"); + ::rptMsg("was last run. According to the KB article, each time MRT is run, a new GUID"); + ::rptMsg("is written to the Version value."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/msis.pl b/thirdparty/rr/plugins/msis.pl new file mode 100644 index 0000000000000000000000000000000000000000..cda7bc4cdd6b38a1c7a32ca32974d1dfd9396e9f --- /dev/null +++ b/thirdparty/rr/plugins/msis.pl @@ -0,0 +1,96 @@ +#----------------------------------------------------------- +# msis.pl +# Plugin to determine the MSI packages installed on the system +# +# Change history: +# 20090911 - created +# +# References: +# http://support.microsoft.com/kb/290134 +# http://support.microsoft.com/kb/931401 +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package msis; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090911); + +sub getConfig{return %config} + +sub getShortDescr { + return "Determine MSI packages installed on the system"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %msi; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching msis v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Classes\\Installer\\Products"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $lastwrite = $s->get_timestamp(); + + my $product; + eval { + $product = $s->get_value("ProductName")->get_data(); + }; + + my $path; + my $pkg; + + eval { + my $p = $s->get_subkey("SourceList")->get_value("LastUsedSource")->get_data(); + $path = (split(/;/,$p,3))[2]; + }; + + eval { + $pkg = $s->get_subkey("SourceList")->get_value("PackageName")->get_data(); + }; + + push(@{$msi{$lastwrite}},$product.";".$path.$pkg); + } + + + foreach my $t (reverse sort {$a <=> $b} keys %msi) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$msi{$t}}) { + ::rptMsg(" ".$item); + } + } + + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/mspaper.pl b/thirdparty/rr/plugins/mspaper.pl new file mode 100644 index 0000000000000000000000000000000000000000..da25ba65a09e61c3418e39d7cf3e28cbd888d442 --- /dev/null +++ b/thirdparty/rr/plugins/mspaper.pl @@ -0,0 +1,100 @@ +#----------------------------------------------------------- +# mspaper.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# MSPaper Recent File List values +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package mspaper; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets images listed in user's MSPaper key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching mspaper v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $tick = 0; + my $key_path = 'Software\\Microsoft'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my @subkeys = $key->get_list_of_subkeys(); + + if (scalar @subkeys > 0) { + foreach my $sk (@subkeys) { + if ($sk->get_name() =~ m/^mspaper/i) { + $tick = 1; + my $nkey = $sk->get_name()."\\Recent File List"; + my $msp; + if ($msp = $key->get_subkey($nkey)) { + ::rptMsg("MSPaper - Recent File List"); + ::rptMsg($key_path."\\".$nkey); + ::rptMsg("LastWrite Time ".gmtime($msp->get_timestamp())." (UTC)"); + my @vals = $msp->get_list_of_values(); + if (scalar(@vals) > 0) { + my %files; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/File/,$val))[1]; + $files{$tag} = $val.":".$data; + } +# Print sorted content to report file + foreach my $u (sort {$a <=> $b} keys %files) { + my ($val,$data) = split(/:/,$files{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path."\\".$nkey." has no values."); + } + } + else { + ::rptMsg($key_path."\\".$nkey." not found."); + ::logMsg("Error: ".$key_path."\\".$nkey." not found."); + } + } + } + if ($tick == 0) { + ::rptMsg("SOFTWARE\\Microsoft\\MSPaper* not found."); + ::logMsg("SOFTWARE\\Microsoft\\MSPaper* not found."); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/muicache.pl b/thirdparty/rr/plugins/muicache.pl new file mode 100644 index 0000000000000000000000000000000000000000..8a980e3531d43d26da8743515c185ffb166cd17d --- /dev/null +++ b/thirdparty/rr/plugins/muicache.pl @@ -0,0 +1,66 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# muicache.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# MUICache values +# +# Change history +# +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package muicache; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets EXEs from user's MUICache key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching muicache v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + my $key_path = 'Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("MUICache"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + next if ($name =~ m/^@/ || $name eq "LangID"); + my $data = $v->get_data(); + ::rptMsg("\t".$name." (".$data.")"); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/nero.pl b/thirdparty/rr/plugins/nero.pl new file mode 100644 index 0000000000000000000000000000000000000000..30b861326a30a141d8b29384a48331a680107061 --- /dev/null +++ b/thirdparty/rr/plugins/nero.pl @@ -0,0 +1,75 @@ +#----------------------------------------------------------- +# nero.pl +# **Very Beta! Based on one sample hive file only! +# +# Change history +# 20100218 - created +# +# References +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package nero; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100218); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of Ahead\\Nero Recent File List subkeys"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my @nerosubkeys = ("Cover Designer","FlmgPlg","Nero PhotoSnap", + "NSPluginMgr","PhotoEffects","XlmgPlg"); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + my %hist; + ::logMsg("Launching nero v.".$VERSION); + + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Ahead'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + foreach my $nsk (@nerosubkeys) { + eval { + my $nk; + if ($nk = $key->get_subkey($nsk."\\Recent File List")) { + my @vals = $nk->get_list_of_values(); + if (scalar @vals > 0) { + ::rptMsg($nsk."\\Recent File List"); + ::rptMsg("LastWrite Time ".gmtime($nk->get_timestamp())." (UTC)"); + foreach my $v (@vals) { + ::rptMsg(" ".$v->get_name()." -> ".$v->get_data()); + } + ::rptMsg(""); + } + else { + ::rptMsg($nsk."\\Recent File List has no values."); + } + } + }; + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/network.pl b/thirdparty/rr/plugins/network.pl new file mode 100644 index 0000000000000000000000000000000000000000..32853b31105d4b4624edb737dba119506c96b5e6 --- /dev/null +++ b/thirdparty/rr/plugins/network.pl @@ -0,0 +1,95 @@ +#----------------------------------------------------------- +# network.pl +# Plugin for Registry Ripper; Get information on network +# interfaces from the System hive file - from the +# Control\Network GUID subkeys... +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package network; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets info from System\\Control\\Network GUIDs"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %nics; + my $ccs; + ::logMsg("Launching network v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + my $nw_path = $ccs."\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; + my $nw; + if ($nw = $root_key->get_subkey($nw_path)) { + ::rptMsg("Network key"); + ::rptMsg($nw_path); +# Get all of the subkey names + my @sk = $nw->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + my $name = $s->get_name(); + next if ($name eq "Descriptions"); + if (my $conn = $nw->get_subkey($name."\\Connection")) { + ::rptMsg("Interface ".$name); + ::rptMsg("LastWrite time ".gmtime($conn->get_timestamp())." (UTC)"); + my %conn_vals; + my @vals = $conn->get_list_of_values(); + map{$conn_vals{$_->get_name()} = $_->get_data()}@vals; + ::rptMsg("\tName = ".$conn_vals{Name}); + ::rptMsg("\tPnpInstanceID = ".$conn_vals{PnpInstanceID}); + ::rptMsg("\tMediaSubType = ".$conn_vals{MediaSubType}); + ::rptMsg("\tIpCheckingEnabled = ".$conn_vals{IpCheckingEnabled}) + if (exists $conn_vals{IpCheckingEnabled}); + + } + ::rptMsg(""); + } + + } + else { + ::rptMsg($nw_path." has no subkeys."); + } + } + else { + ::rptMsg($nw_path." could not be found."); + ::logMsg($nw_path." could not be found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/networkcards.pl b/thirdparty/rr/plugins/networkcards.pl new file mode 100644 index 0000000000000000000000000000000000000000..c0ce64f41dcbec31d7c858bbce45d60a990b6ed7 --- /dev/null +++ b/thirdparty/rr/plugins/networkcards.pl @@ -0,0 +1,62 @@ +#----------------------------------------------------------- +# networkcards +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package networkcards; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080325); + +sub getConfig{return %config} +sub getShortDescr { + return "Get NetworkCards"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching networkcards v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("NetworkCards"); + ::rptMsg($key_path); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + my %nc; + foreach my $s (@subkeys) { + my $service = $s->get_value("ServiceName")->get_data(); + $nc{$service}{descr} = $s->get_value("Description")->get_data(); + $nc{$service}{lastwrite} = $s->get_timestamp(); + } + + foreach my $n (keys %nc) { + ::rptMsg($nc{$n}{descr}." [".gmtime($nc{$n}{lastwrite})."]"); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/networklist.pl b/thirdparty/rr/plugins/networklist.pl new file mode 100644 index 0000000000000000000000000000000000000000..babf87d7d647e3d120a54c44b8396fd6a2e58913 --- /dev/null +++ b/thirdparty/rr/plugins/networklist.pl @@ -0,0 +1,142 @@ +#----------------------------------------------------------- +# networklist.pl - Plugin to extract information from the +# NetworkList key, including the MAC address of the default +# gateway +# +# +# Change History: +# 20090812 - updated code to parse DateCreated and DateLastConnected +# values; modified output, as well +# 20090811 - created +# +# References +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package networklist; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090811); + +sub getConfig{return %config} + +sub getShortDescr { + return "Collects network info from Vista NetworkList key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching networklist v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $base_path = "Microsoft\\Windows NT\\CurrentVersion\\NetworkList"; + +# First, get profile info + my $key_path = $base_path."\\Profiles"; + my $key; + my %nl; # hash of hashes to hold data + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + my $name = $s->get_name(); + $nl{$name}{LastWrite} = $s->get_timestamp(); + eval { + $nl{$name}{ProfileName} = $s->get_value("ProfileName")->get_data(); + $nl{$name}{Description} = $s->get_value("Description")->get_data(); + $nl{$name}{Managed} = $s->get_value("Managed")->get_data(); + + my $create = $s->get_value("DateCreated")->get_data(); + $nl{$name}{DateCreated} = parseDate128($create) if (length($create) == 16); + my $conn = $s->get_value("DateLastConnected")->get_data(); + $nl{$name}{DateLastConnected} = parseDate128($conn) if (length($conn) == 16); + +# $nl{$name}{NameType} = $s->get_value("ProfileName")->get_data(); + }; + } + +# Get additional information from the Signatures subkey + $key_path = $base_path."\\Signatures\\Managed"; + if ($key = $root_key->get_subkey($key_path)) { + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + eval { + my $prof = $s->get_value("ProfileGuid")->get_data(); + my $tmp = substr($s->get_value("DefaultGatewayMac")->get_data(),0,6); + my $mac = uc(unpack("H*",$tmp)); + my @t = split(//,$mac); + $nl{$prof}{DefaultGatewayMac} = $t[0].$t[1]."-".$t[2].$t[3]. + "-".$t[4].$t[5]."-".$t[6].$t[7]."-".$t[8].$t[9]."-".$t[10].$t[11]; + }; + } + } + } + + $key_path = $base_path."\\Signatures\\Unmanaged"; + if ($key = $root_key->get_subkey($key_path)) { + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + eval { + my $prof = $s->get_value("ProfileGuid")->get_data(); + my $tmp = substr($s->get_value("DefaultGatewayMac")->get_data(),0,6); + my $mac = uc(unpack("H*",$tmp)); + my @t = split(//,$mac); + $nl{$prof}{DefaultGatewayMac} = $t[0].$t[1]."-".$t[2].$t[3]. + "-".$t[4].$t[5]."-".$t[6].$t[7]."-".$t[8].$t[9]."-".$t[10].$t[11]; + }; + } + } + } + +# Now, display the information + foreach my $n (keys %nl) { + my $str = sprintf "%-15s Gateway Mac: ".$nl{$n}{DefaultGatewayMac},$nl{$n}{ProfileName}; + ::rptMsg($nl{$n}{ProfileName}); + ::rptMsg(" Key LastWrite : ".gmtime($nl{$n}{LastWrite})." UTC"); + ::rptMsg(" DateLastConnected: ".$nl{$n}{DateLastConnected}); + ::rptMsg(" DateCreated : ".$nl{$n}{DateCreated}); + ::rptMsg(" DefaultGatewayMac: ".$nl{$n}{DefaultGatewayMac}); + ::rptMsg(""); + } + + } + else { + ::rptMsg($key_path." has not subkeys"); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + + + +sub parseDate128 { + my $date = $_[0]; + my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul", + "Aug","Sep","Oct","Nov","Dec"); + my @days = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat"); + my ($yr,$mon,$dow,$dom,$hr,$min,$sec,$ms) = unpack("v*",$date); + $hr = "0".$hr if ($hr < 10); + $min = "0".$min if ($min < 10); + $sec = "0".$sec if ($sec < 10); + my $str = $days[$dow]." ".$months[$mon - 1]." ".$dom." ".$hr.":".$min.":".$sec." ".$yr; + return $str; +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/networkuid.pl b/thirdparty/rr/plugins/networkuid.pl new file mode 100644 index 0000000000000000000000000000000000000000..7a457e111f3d493e4e165a7133dda6c1f7cd6751 --- /dev/null +++ b/thirdparty/rr/plugins/networkuid.pl @@ -0,0 +1,57 @@ +#----------------------------------------------------------- +# networkuid.pl +# Gets UID value from Network key +# +# References +# http://blogs.technet.com/mmpc/archive/2010/03/11/got-zbot.aspx +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package networkuid; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100312); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets Network key UID value"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching networkuid v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Network"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite time = ".gmtime($key->get_timestamp())); + ::rptMsg(""); + + eval { + my $uid = $key->get_value("UID")->get_data(); + ::rptMsg("UID value = ".$uid); + }; + ::rptMsg("UID value not found.") if ($@); + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/nic.pl b/thirdparty/rr/plugins/nic.pl new file mode 100644 index 0000000000000000000000000000000000000000..f176150a92dcc485ddf23e855ab83d089e3c2906 --- /dev/null +++ b/thirdparty/rr/plugins/nic.pl @@ -0,0 +1,80 @@ +#----------------------------------------------------------- +# nic.pl +# +# +# Change history +# 20100401 - created +# +# References +# LeaseObtainedTime - http://technet.microsoft.com/en-us/library/cc978465.aspx +# T1 - http://technet.microsoft.com/en-us/library/cc978470.aspx +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package nic; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100401); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets NIC info from System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %nics; + my $ccs; + ::logMsg("Launching nic v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + eval { + $current = $root_key->get_subkey("Select")->get_value("Current")->get_data(); + }; + my @nics; + my $key_path = "ControlSet00".$current."\\Services"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my @svcs = $key->get_list_of_subkeys(); + foreach my $s (@svcs) { + push(@nics,$s) if ($s->get_name() =~ m/^{/); + } + foreach my $n (@nics) { + eval { + my @vals = $n->get_subkey("Parameters\\Tcpip")->get_list_of_values(); + ::rptMsg("Adapter: ".$n->get_name()); + ::rptMsg("LastWrite Time: ".gmtime($n->get_timestamp())." Z"); + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + $data = gmtime($data)." Z" if ($name eq "T1" || $name eq "T2"); + $data = gmtime($data)." Z" if ($name =~ m/Time$/); + + ::rptMsg(sprintf " %-20s %-20s",$name,$data); + + } + ::rptMsg(""); + }; + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/nic2.pl b/thirdparty/rr/plugins/nic2.pl new file mode 100644 index 0000000000000000000000000000000000000000..44d4d8099a07ab12678a9a4912254adb0dc1eb5d --- /dev/null +++ b/thirdparty/rr/plugins/nic2.pl @@ -0,0 +1,80 @@ +#----------------------------------------------------------- +# nic2.pl +# +# +# Change history +# 20100401 - created +# +# References +# LeaseObtainedTime - http://technet.microsoft.com/en-us/library/cc978465.aspx +# T1 - http://technet.microsoft.com/en-us/library/cc978470.aspx +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package nic2; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100401); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets NIC info from System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %nics; + my $ccs; + ::logMsg("Launching nic v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + eval { + $current = $root_key->get_subkey("Select")->get_value("Current")->get_data(); + }; + my @nics; + my $key_path = "ControlSet00".$current."\\Services\\Tcpip\\Parameters\\Interfaces"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my @guids = $key->get_list_of_subkeys(); + if (scalar @guids > 0) { + foreach my $g (@guids) { + ::rptMsg("Adapter: ".$g->get_name()); + ::rptMsg("LastWrite Time: ".gmtime($g->get_timestamp())." Z"); + eval { + my @vals = $g->get_list_of_values(); + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + $data = gmtime($data)." Z" if ($name eq "T1" || $name eq "T2"); + $data = gmtime($data)." Z" if ($name =~ m/Time$/); + ::rptMsg(sprintf " %-28s %-20s",$name,$data); + } + ::rptMsg(""); + }; + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/nic_mst2.pl b/thirdparty/rr/plugins/nic_mst2.pl new file mode 100644 index 0000000000000000000000000000000000000000..36c98b42708335c8e9bb9bd863bbf131a6a68353 --- /dev/null +++ b/thirdparty/rr/plugins/nic_mst2.pl @@ -0,0 +1,148 @@ +#----------------------------------------------------------- +# nic_mst2.pl +# Plugin for Registry Ripper; Get information on network +# interfaces from the System hive file - start with the +# Control\Network GUID subkeys...within the Connection key, +# look for MediaSubType == 2, and maintain a list of GUIDs. +# Then go over to the Services\Tcpip\Parameters\Interfaces +# key and get the IP configurations for each of the interface +# GUIDs +# +# Change history +# +# +# References +# http://support.microsoft.com/kb/555382 +# http://support.microsoft.com/kb/894564 +# http://support.microsoft.com/kb/899868 +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package nic_mst2; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets NICs from System hive; looks for MediaType = 2"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %nics; + my $ccs; + ::logMsg("Launching nic_mst2 v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + my $nw_path = $ccs."\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; + my $nw; + if ($nw = $root_key->get_subkey($nw_path)) { + ::rptMsg("Network key"); + ::rptMsg($nw_path); +# Get all of the subkey names + my @sk = $nw->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + my $name = $s->get_name(); + next if ($name eq "Descriptions"); + if (my $conn = $nw->get_subkey($name."\\Connection")) { + my %conn_vals; + my @vals = $conn->get_list_of_values(); + map{$conn_vals{$_->get_name()} = $_->get_data()}@vals; +# See what the active NICs were on the system; "active" based on PnpInstanceID having +# a string value +# Get the GUID of the interface, the name, and the LastWrite time of the Connection +# key + if (exists $conn_vals{PnpInstanceID} && $conn_vals{PnpInstanceID} ne "") { + $nics{$name}{Name} = $conn_vals{Name}; + $nics{$name}{LastWrite} = $conn->get_timestamp(); + } + } + } + + } + else { + ::rptMsg($nw_path." has no subkeys."); + } + } + else { + ::rptMsg($nw_path." could not be found."); + } + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); +# access the Tcpip Services key to get the IP address information + if (scalar(keys %nics) > 0) { + my $key_path = $ccs."\\Services\\Tcpip\\Parameters\\Interfaces"; + if ($key = $root_key->get_subkey($key_path)) { + my %guids; + ::rptMsg($key_path); + ::rptMsg("LastWrite time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); +# Dump the names of the subkeys under Parameters\Interfaces into a hash + my @sk = $key->get_list_of_subkeys(); + map{$guids{$_->get_name()} = 1}(@sk); + + foreach my $n (keys %nics) { + if (exists $guids{$n}) { + my $if = $key->get_subkey($n); + ::rptMsg("Interface ".$n); + ::rptMsg("Name: ".$nics{$n}{Name}); + ::rptMsg("Control\\Network key LastWrite time ".gmtime($nics{$n}{LastWrite})." (UTC)"); + ::rptMsg("Services\\Tcpip key LastWrite time ".gmtime($if->get_timestamp())." (UTC)"); + + my @vals = $if->get_list_of_values; + my %ip; + map{$ip{$_->get_name()} = $_->get_data()}@vals; + + if (exists $ip{EnableDHCP} && $ip{EnableDHCP} == 1) { + ::rptMsg("\tDhcpDomain = ".$ip{DhcpDomain}); + ::rptMsg("\tDhcpIPAddress = ".$ip{DhcpIPAddress}); + ::rptMsg("\tDhcpSubnetMask = ".$ip{DhcpSubnetMask}); + ::rptMsg("\tDhcpNameServer = ".$ip{DhcpNameServer}); + ::rptMsg("\tDhcpServer = ".$ip{DhcpServer}); + } + else { + ::rptMsg("\tIPAddress = ".$ip{IPAddress}); + ::rptMsg("\tSubnetMask = ".$ip{SubnetMask}); + ::rptMsg("\tDefaultGateway = ".$ip{DefaultGateway}); + } + + } + else { + ::rptMsg("Interface ".$n." not found in the ".$key_path." key."); + } + ::rptMsg(""); + } + } + } + else { + ::rptMsg("No active network interface cards were found."); + ::logMsg("No active network interface cards were found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/nolmhash.pl b/thirdparty/rr/plugins/nolmhash.pl new file mode 100644 index 0000000000000000000000000000000000000000..94f253e63d3c893f528a115055f60083068f36d7 --- /dev/null +++ b/thirdparty/rr/plugins/nolmhash.pl @@ -0,0 +1,74 @@ +#----------------------------------------------------------- +# nolmhash.pl +# Gets NoLMHash value +# +# Change history +# 20100712 - created +# +# References +# http://support.microsoft.com/kb/299656 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package nolmhash; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100712); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets NoLMHash value"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching lsa v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my ($current,$ccs); + my $sel_path = 'Select'; + my $sel; + if ($sel = $root_key->get_subkey($sel_path)) { + $current = $sel->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + my $key_path = $ccs."\\Control\\Lsa"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("nolmhash v.".$VERSION); + ::rptMsg($key_path); + ::rptMsg("LastWrite: ".gmtime($key->get_timestamp())); + ::rptMsg(""); + my $nolmhash; + eval { + $nolmhash = $key->get_value("NoLMHash")->get_data(); + ::rptMsg("NoLMHash value = ".$nolmhash); + ::rptMsg(""); + ::rptMsg("A value of 1 indicates that LMHashes are not stored in the SAM."); + }; + ::rptMsg("Error occurred getting NoLMHash value: $@") if ($@); + } + else { + ::rptMsg($key_path." not found."); + } + } + else { + ::rptMsg($sel_path." not found."); + ::logMsg($sel_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/notify.pl b/thirdparty/rr/plugins/notify.pl new file mode 100644 index 0000000000000000000000000000000000000000..8919b6dbd9ff6c9d1b8db806f6d616c7eedb1bd3 --- /dev/null +++ b/thirdparty/rr/plugins/notify.pl @@ -0,0 +1,79 @@ +#----------------------------------------------------------- +# notify.pl +# +# +# Change History: +# 20110309 - updated output format to sort entries based on +# LastWrite time +# 20110308 - created +# +# References +# http://blogs.technet.com/b/markrussinovich/archive/2011/03/08/3392087.aspx +# +# copyright 2011 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package notify; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20110309); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get Notify subkey entries"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my %notify; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching notify v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("notify"); + ::rptMsg($key_path); + ::rptMsg(""); + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + my $name = $s->get_name(); + my $lw = $s->get_timestamp(); + my $dll; + eval { + $dll = $s->get_value("DLLName")->get_data(); + push(@{$notify{$lw}},sprintf "%-15s %-25s",$name,$dll); + }; + } + + foreach my $t (reverse sort {$a <=> $b} keys %notify) { + ::rptMsg(gmtime($t)." UTC"); + foreach my $i (@{$notify{$t}}) { + ::rptMsg(" ".$i); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ntuser b/thirdparty/rr/plugins/ntuser new file mode 100644 index 0000000000000000000000000000000000000000..f2d6b0a3666232c8fc373e52cd021d8335c19c80 --- /dev/null +++ b/thirdparty/rr/plugins/ntuser @@ -0,0 +1,50 @@ +# List of plugins for the Registry Ripper + +#------------------------------------- +# NTUSER.DAT +logonusername +autoendtasks +autorun +acmru +adoberdr +aim +applets +comdlg32 +compdesc +# The controlpanel plugin is intended for Vista systems only +# User hives from systems prior to Vista will show 'not found' +controlpanel +listsoft +logon_xp_run +load +mmc +mndmru +mp2 +mpmru +mspaper +officedocs +oisc +recentdocs +realplayer6 +runmru +tsclient +ie_main +ie_settings +typedurls +muicache +#userassist +userassist2 +user_run +userlocsvc +vncviewer +winzip +user_win +winrar +winlogon_u +policies_u +wallpaper +vista_bitbucket +shellfolders +arpcache +clampitm +unreadmail \ No newline at end of file diff --git a/thirdparty/rr/plugins/officedocs.pl b/thirdparty/rr/plugins/officedocs.pl new file mode 100644 index 0000000000000000000000000000000000000000..8182a3d177a67f68132cc22795097ddd2a9b978f --- /dev/null +++ b/thirdparty/rr/plugins/officedocs.pl @@ -0,0 +1,145 @@ +#----------------------------------------------------------- +# officedocs.pl +# Plugin for Registry Ripper +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package officedocs; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's Office doc MRU keys"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching officedocs v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + ::rptMsg("officedocs v.".$VERSION); +# First, let's find out which version of Office is installed + my $version; + my $tag = 0; + my @versions = ("7\.0","8\.0", "9\.0", "10\.0", "11\.0","12\.0"); + foreach my $ver (@versions) { + my $key_path = "Software\\Microsoft\\Office\\".$ver."\\Common\\Open Find"; + if (defined($root_key->get_subkey($key_path))) { + $version = $ver; + $tag = 1; + } + } + + if ($tag) { + ::rptMsg("MSOffice version ".$version." located."); + my $key_path = "Software\\Microsoft\\Office\\".$version; + my $of_key = $root_key->get_subkey($key_path); + if ($of_key) { +# Attempt to retrieve Word docs + my @funcs = ("Open","Save As","File Save"); + foreach my $func (@funcs) { + my $word = "Common\\Open Find\\Microsoft Office Word\\Settings\\".$func."\\File Name MRU"; + my $word_key = $of_key->get_subkey($word); + if ($word_key) { + ::rptMsg($word); + ::rptMsg("LastWrite Time ".gmtime($word_key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $value = $word_key->get_value("Value")->get_data(); + my @data = split(/\00/,$value); + map{::rptMsg("$_");}@data; + } + else { +# ::rptMsg("Could not access ".$word); + } + ::rptMsg(""); + } +# Attempt to retrieve Excel docs + my $excel = 'Excel\\Recent Files'; + if (my $excel_key = $of_key->get_subkey($excel)) { + ::rptMsg($key_path."\\".$excel); + ::rptMsg("LastWrite Time ".gmtime($excel_key->get_timestamp())." (UTC)"); + my @vals = $excel_key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %files; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/File/,$val))[1]; + $files{$tag} = $val.":".$data; + } +# Print sorted content to report file + foreach my $u (sort {$a <=> $b} keys %files) { + my ($val,$data) = split(/:/,$files{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path.$excel." has no values."); + } + } + else { + ::rptMsg($key_path.$excel." not found."); + } + ::rptMsg(""); +# Attempt to retrieve PowerPoint docs + my $ppt = 'PowerPoint\\Recent File List'; + if (my $ppt_key = $of_key->get_subkey($ppt)) { + ::rptMsg($key_path."\\".$ppt); + ::rptMsg("LastWrite Time ".gmtime($ppt_key->get_timestamp())." (UTC)"); + my @vals = $ppt_key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %files; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/File/,$val))[1]; + $files{$tag} = $val.":".$data; + } +# Print sorted content to report file + foreach my $u (sort {$a <=> $b} keys %files) { + my ($val,$data) = split(/:/,$files{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path."\\".$ppt." has no values."); + } + } + else { + ::rptMsg($key_path."\\".$ppt." not found."); + } + } + else { + ::rptMsg("Could not access ".$key_path); + ::logMsg("Could not access ".$key_path); + } + } + else { + ::logMsg("MSOffice version not found."); + ::rptMsg("MSOffice version not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/oisc.pl b/thirdparty/rr/plugins/oisc.pl new file mode 100644 index 0000000000000000000000000000000000000000..2ddad0697396c99d788ddc49e8084dc449247033 --- /dev/null +++ b/thirdparty/rr/plugins/oisc.pl @@ -0,0 +1,123 @@ +#----------------------------------------------------------- +# oisc.pl +# Plugin for Registry Ripper +# +# Change history +# 20091125 - modified by H. Carvey +# 20091110 - created +# +# References +# http://support.microsoft.com/kb/838028 +# http://support.microsoft.com/kb/916658 +# +# Derived from the officeDocs plugin +# copyright 2008-2009 H. Carvey, mangled 2009 M. Tarnawsky +# +# Michael Tarnawsky +# forensics@mialta.com +#----------------------------------------------------------- +package oisc; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20091125); + +my %prot = (0 => "Read-only HTTP", + 1 => "WEC to FPSE-enabled web folder", + 2 => "DAV to DAV-ext. web folder"); + +my %types = (0 => "no collaboration", + 1 => "SharePoint Team Server", + 2 => "Exchange 2000 Server", + 3 => "SharePoint Portal 2001 Server", + 4 => "SharePoint 2001 enhanced folder", + 5 => "Windows SharePoint Server/SharePoint Portal 2003 Server"); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's Office Internet Server Cache"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching oisc v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; +# First, let's find out which version of Office is installed + my $version; + my $tag = 0; + my @versions = ("7\.0","8\.0", "9\.0", "10\.0", "11\.0","12\.0"); + foreach my $ver (@versions) { + my $key_path = "Software\\Microsoft\\Office\\".$ver."\\Common\\Internet\\Server Cache"; + if (defined($root_key->get_subkey($key_path))) { + $version = $ver; + $tag = 1; + } + } + + if ($tag) { + + my %isc; + + ::rptMsg("MSOffice version ".$version." located."); + my $key_path = "Software\\Microsoft\\Office\\".$version."\\Common\\Internet\\Server Cache"; + my $sc_key; + if ($sc_key = $root_key->get_subkey($key_path)) { +# Attempt to retrieve Servers Cache subkeys + my @sc = ($sc_key->get_list_of_subkeys()); + if (scalar(@sc) > 0) { + foreach my $s (@sc) { + my $name = $s->get_name(); + $isc{$name}{lastwrite} = $s->get_timestamp(); + + eval { + my $t = $s->get_value("Type")->get_data(); + (exists $types{$t}) ? ($isc{$name}{type} = $types{$t}) + : ($isc{$name}{type} = $t); + }; + + eval { + my $p = $s->get_value("Protocol")->get_data(); + (exists $prot{$p}) ? ($isc{$name}{protocol} = $prot{$p}) + : ($isc{$name}{protocol} = $p); + }; + + eval { + my @e = unpack("VV",$s->get_value("Expiration")->get_data()); + $isc{$name}{expiry} = ::getTime($e[0],$e[1]); + }; + } + ::rptMsg(""); + foreach my $i (keys %isc) { + ::rptMsg($i); + ::rptMsg(" LastWrite : ".gmtime($isc{$i}{lastwrite})." UTC"); + ::rptMsg(" Expiry : ".gmtime($isc{$i}{expiry})." UTC"); + ::rptMsg(" Protocol : ".$isc{$i}{protocol}); + ::rptMsg(" Type : ".$isc{$i}{type}); + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } + } + else { + ::rptMsg("MSOffice version not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/outlook.pl b/thirdparty/rr/plugins/outlook.pl new file mode 100644 index 0000000000000000000000000000000000000000..eafc9b3ade16c0b2733ba9f969009b0153a145b3 --- /dev/null +++ b/thirdparty/rr/plugins/outlook.pl @@ -0,0 +1,186 @@ +#----------------------------------------------------------- +# outlook.pl +# **Very Beta! Based on one sample hive file only! +# +# Change history +# 20100218 - created +# +# References +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package outlook; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100218); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets user's Outlook settings"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + my %hist; + ::logMsg("Launching outlook v.".$VERSION); + + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + ::rptMsg(""); + foreach my $s (@subkeys) { + + my $profile = $s->get_name(); + ::rptMsg($profile." Profile"); + +# AutoArchive settings +# http://support.microsoft.com/kb/198479 + eval { + my $data = $s->get_subkey("0a0d020000000000c000000000000046")->get_value("001f0324")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Outlook 2007 AutoArchive path -> ".$data); + }; + + eval { + my $data = $s->get_subkey("0a0d020000000000c000000000000046")->get_value("001e0324")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Outlook 2003 AutoArchive path -> ".$data); + }; + + eval { + my $data = $s->get_subkey("0a0d020000000000c000000000000046")->get_value("001e032c")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Outlook 2003 AutoArchive path (alt) -> ".$data); + }; + +# http://support.microsoft.com/kb/288570 + eval { + my $data = $s->get_subkey("0a0d020000000000c000000000000046")->get_value("101e0384")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Open Other Users MRU (Outlook 97) -> ".$data); + }; + + eval { + my $data = $s->get_subkey("0a0d020000000000c000000000000046")->get_value("101f0390")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Open Other Users MRU (Outlook 2003) -> ".$data); + }; + + + + eval { + my $data = unpack("V",$s->get_subkey("13dbb0c8aa05101a9bb000aa002fc45a")->get_value("00036601")->get_data()); + my $str; + if ($data == 4) { + $str = " Cached Exchange Mode disabled."; + } + elsif ($data == 4484) { + $str = " Cached Exchange Mode enabled."; + } + else { + $str = sprintf " Cached Exchange Mode: 0x%x",$data; + } + ::rptMsg($str); + }; + + eval { + my $data = $s->get_subkey("13dbb0c8aa05101a9bb000aa002fc45a")->get_value("001f6610")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Path to OST file: ".$data); + }; + + eval { + my $data = $s->get_subkey("13dbb0c8aa05101a9bb000aa002fc45a")->get_value("001f6607")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Email: ".$data); + }; + + eval { + my $data = $s->get_subkey("13dbb0c8aa05101a9bb000aa002fc45a")->get_value("001f6620")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Email: ".$data); + }; + +# http://support.microsoft.com/kb/959956 +# eval { +# my $data = $s->get_subkey("13dbb0c8aa05101a9bb000aa002fc45a")->get_value("01026687")->get_data(); +# $data =~ s/\00/\./g; +# $data =~ s/\W//g; +# ::rptMsg(" Non-SMTP Email: ".$data); +# }; + + + + + + + + + + + + + + + eval { + my $data = $s->get_subkey("0a0d020000000000c000000000000046")->get_value("001e032c")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" Outlook 2003 AutoArchive path (alt) -> ".$data); + }; + + + + + + + eval { + my $data = $s->get_subkey("0a0d020000000000c000000000000046")->get_value("001f0418")->get_data(); + $data =~ s/\00//g; + ::rptMsg(" 001f0418 -> ".$data); + }; +# ::rptMsg("Error : ".$@) if ($@); + + +# Account Names and signatures +# http://support.microsoft.com/kb/938360 + my @subkeys = $s->get_subkey("9375CFF0413111d3B88A00104B2A6676")->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + + foreach my $s2 (@subkeys) { + eval { + + + }; + } + } + + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/pagefile.pl b/thirdparty/rr/plugins/pagefile.pl new file mode 100644 index 0000000000000000000000000000000000000000..f0484de43169f3628d117b2474caca9dfb0ff05b --- /dev/null +++ b/thirdparty/rr/plugins/pagefile.pl @@ -0,0 +1,71 @@ +#----------------------------------------------------------- +# pagefile.pl +# +# Ref: +# +# http://support.microsoft.com/kb/314834 - ClearPagefileAtShutdown +# +# copyright 2008-2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package pagefile; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081212); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get info on pagefile(s)"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching pagefile v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + + my $mm_path = "ControlSet00".$current."\\Control\\Session Manager\\Memory Management"; + my $mm; + if ($mm = $root_key->get_subkey($mm_path)) { + + eval { + my $files = $mm->get_value("PagingFiles")->get_data(); + ::rptMsg("PagingFiles = ".$files); + }; + ::rptMsg($@) if ($@); + + eval { + my $cpf = $mm->get_value("ClearPageFileAtShutdown")->get_data(); + ::rptMsg("ClearPageFileAtShutdown = ".$cpf); + }; + + } + else { + ::rptMsg($mm_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; diff --git a/thirdparty/rr/plugins/polacdms.pl b/thirdparty/rr/plugins/polacdms.pl new file mode 100644 index 0000000000000000000000000000000000000000..83efc86670d858e4fb11a2db9dd8c9d978e16830 --- /dev/null +++ b/thirdparty/rr/plugins/polacdms.pl @@ -0,0 +1,93 @@ +#----------------------------------------------------------- +# polacdms +# Get the audit policy from the Security hive file; also, gets +# +# +# Change History: +# 20100531 - Created +# +# References: +# http://en.wikipedia.org/wiki/Security_Identifier +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package polacdms; +use strict; + +my %config = (hive => "Security", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100531); + +sub getConfig{return %config} +sub getShortDescr { + return "Get local machine SID from Security hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching polacdms v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Policy\\PolAcDmS"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("PolAcDmS"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $data; + eval { + $data = $key->get_value("")->get_data(); + }; + if ($@) { + ::rptMsg("Error occurred getting data from ".$key_path); + ::rptMsg(" - ".$@); + } + else { + my @d = unpack("V4",substr($data,8,16)); + ::rptMsg("Machine SID: S-1-5-".(join('-',@d))); + } + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); + my $key_path = "Policy\\PolPrDmS"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("PolPrDmS"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $data; + eval { + $data = $key->get_value("")->get_data(); + }; + if ($@) { + ::rptMsg("Error occurred getting data from ".$key_path); + ::rptMsg(" - ".$@); + } + else { + my @d = unpack("V4",substr($data,8,16)); + ::rptMsg("Primary Domain SID: S-1-5-".(join('-',@d))); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/policies_u.pl b/thirdparty/rr/plugins/policies_u.pl new file mode 100644 index 0000000000000000000000000000000000000000..9a15c131124053e686181634e9d467353da6caf8 --- /dev/null +++ b/thirdparty/rr/plugins/policies_u.pl @@ -0,0 +1,73 @@ +#----------------------------------------------------------- +# policies_u +# Get values from user's WinLogon key +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package policies_u; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20091021); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get values from the user's Policies key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching policies_u v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion"; + my $key; + if ($key = $root_key->get_subkey($key_path."\\policies")) { +# ::rptMsg("policies key found."); + + } + elsif ($key = $root_key->get_subkey($key_path."\\Policies")) { +# ::rptMsg("Policies key found."); + + } + else { + ::rptMsg("Neither policies nor Policies key found."); + return; + } + + eval { + my @vals = $key->get_subkey("Explorer")->get_list_of_values(); + if (scalar(@vals) > 0) { + ::rptMsg(""); + ::rptMsg("Explorer subkey values:"); + foreach my $v (@vals) { + my $str = sprintf "%-20s %-20s",$v->get_name(),$v->get_data(); + ::rptMsg(" ".$str); + } + } + }; + ::rptMsg(""); + eval { + my $quota = $key->get_subkey("System")->get_value("EnableProfileQuota")->get_data(); + ::rptMsg("EnableProfileQuota = ".$quota); + ::rptMsg(""); + ::rptMsg("The EnableProfileQuota = 1 setting causes the proquota\.exe to be run"); + ::rptMsg("automatically in order to limit the size of roaming profiles\. This"); + ::rptMsg("corresponds to the Limit Profile Size GPO setting\."); + }; + ::rptMsg("System\\EnableProfileQuota value not found\.") if ($@); +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/port_dev.pl b/thirdparty/rr/plugins/port_dev.pl new file mode 100644 index 0000000000000000000000000000000000000000..3ceaf1ae7336a41ba7e4dabd8eeb726d42ece711 --- /dev/null +++ b/thirdparty/rr/plugins/port_dev.pl @@ -0,0 +1,89 @@ +#----------------------------------------------------------- +# port_dev +# Parse Microsoft\Windows Portable Devices\Devices key on Vista +# Get historical information about drive letter assigned to devices +# +# NOTE: Credit for "discovery" goes to Rob Lee +# +# Change History: +# 20090118 - changed the name of the plugin from "removdev" +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package port_dev; +use strict; + +my %config = (hive => "Software", + osmask => 192, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090118); + +sub getConfig{return %config} + +sub getShortDescr { + return "Parses Windows Portable Devices key (Vista)"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching port_dev v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows Portable Devices\\Devices"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("RemovDev"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + + foreach my $s (@subkeys) { + my $name = $s->get_name(); + my $lastwrite = $s->get_timestamp(); + + my $letter; + eval { + $letter = $s->get_value("FriendlyName")->get_data(); + }; + ::rptMsg($name." key error: $@") if ($@); + + my $half; + if (grep(/##/,$name)) { + $half = (split(/##/,$name))[1]; + } + + if (grep(/\?\?/,$name)) { + $half = (split(/\?\?/,$name))[1]; + } + + my ($dev,$sn) = (split(/#/,$half))[1,2]; + + ::rptMsg("Device : ".$dev); + ::rptMsg("LastWrite : ".gmtime($lastwrite)." (UTC)"); + ::rptMsg("SN : ".$sn); + ::rptMsg("Drive : ".$letter); + ::rptMsg(""); + + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/printermru.pl b/thirdparty/rr/plugins/printermru.pl new file mode 100644 index 0000000000000000000000000000000000000000..531f1f19adbfaa9f93dd195aa9830ea93fe8765e --- /dev/null +++ b/thirdparty/rr/plugins/printermru.pl @@ -0,0 +1,74 @@ +#----------------------------------------------------------- +# printermru.pl +# Plugin to get RealVNC MRU listings from NTUSER.DAT +# +# Change history +# 20091125 - created +# +# References +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package printermru; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20091125); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets user's Printer Wizard MRU listing"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching printermru v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Printers\\Settings\\Wizard\\ConnectMRU'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %mru; + my @list; + foreach my $v (@vals) { + $mru{$v->get_name()} = $v->get_data(); + } + + if (exists $mru{MRUList}) { + @list = split(//,$mru{MRUList}); + } + + ::rptMsg("Printers listed in MRUList order."); + foreach my $i (0..scalar(@list) - 1) { + ::rptMsg(" ".$list[$i]." -> ".$mru{$list[$i]}); + } + + + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/printers.pl b/thirdparty/rr/plugins/printers.pl new file mode 100644 index 0000000000000000000000000000000000000000..b01c920078dc60f2b94e077f0a037bc72f325f72 --- /dev/null +++ b/thirdparty/rr/plugins/printers.pl @@ -0,0 +1,83 @@ +#----------------------------------------------------------- +# printers.pl +# Get information about printers used by a user; System hive +# info is volatile +# +# Ref: +# http://support.microsoft.com/kb/102966 +# http://support.microsoft.com/kb/252388 +# http://support.microsoft.com/kb/102116 +# +# The following references contain information from the System +# hive that is volatile. +# http://www.undocprint.org/winspool/registry +# http://msdn.microsoft.com/en-us/library/aa394363(VS.85).aspx +# +# copyright 2008-2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package printers; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090223); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get user's printers"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching printers v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows NT\\CurrentVersion\\PrinterPorts"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time: ".gmtime($key->get_timestamp())); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + ::rptMsg(" ".$v->get_name()." (".$v->get_data().")"); + } + } + else { + ::rptMsg($key_path." has no values."); + } + ::rptMsg(""); +# Get default printer + my $def_path = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"; + my $def; + eval { + $def = $root_key->get_subkey($def_path)->get_value("Device")->get_data(); + ::rptMsg("Default Printer (via CurrentVersion\\Windows): ".$def); + }; +# another attempt to get the default printer + my $def_path = "Printers"; + my $def; + eval { + $def = $root_key->get_subkey($def_path)->get_value("DeviceOld")->get_data(); + ::rptMsg("Default Printer (via Printers->DeviceOld): ".$def); + }; + + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/product.pl b/thirdparty/rr/plugins/product.pl new file mode 100644 index 0000000000000000000000000000000000000000..6a70d719f496a7dd4cdd438589e856c62cc07c9e --- /dev/null +++ b/thirdparty/rr/plugins/product.pl @@ -0,0 +1,118 @@ +#----------------------------------------------------------- +# product.pl +# Plugin to determine the MSI packages installed on the system +# +# Change history: +# 20100325 - created +# +# References: +# http://support.microsoft.com/kb/236590 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package product; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100325); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get installed product info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %msi; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching product v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Installer\\UserData"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { +# Each of these subkeys should be SIDs + foreach my $s (@subkeys) { + next unless ($s->get_name() =~ m/^S/); + ::rptMsg($s->get_name()); + if ($s->get_subkey("Products")) { + processSIDKey($s->get_subkey("Products")); + ::rptMsg(""); + } + else { + ::rptMsg($s->get_name()."\\Products subkey not found."); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub processSIDKey { + my $key = shift; + my %prod; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { +# ::rptMsg($key->get_name()); + foreach my $s (@subkeys) { + my ($displayname,$lastwrite); + eval { + $displayname = $s->get_subkey("InstallProperties")->get_value("DisplayName")->get_data(); + $lastwrite = $s->get_subkey("InstallProperties")->get_timestamp(); + }; + + my $displayversion; + eval { + $displayversion = $s->get_subkey("InstallProperties")->get_value("DisplayVersion")->get_data(); + }; + + my $installdate; + eval { + $installdate = $s->get_subkey("InstallProperties")->get_value("InstallDate")->get_data(); + }; + + my $str = $displayname." v.".$displayversion.", ".$installdate; + push(@{$prod{$lastwrite}},$str); + } + + foreach my $t (reverse sort {$a <=> $b} keys %prod) { + ::rptMsg(gmtime($t)." Z"); + foreach my $i (@{$prod{$t}}) { + ::rptMsg(" ".$i); + } + } + + + } + else { + ::rptMsg($key->get_name()." has no subkeys."); + return; + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/productpolicy.pl b/thirdparty/rr/plugins/productpolicy.pl new file mode 100644 index 0000000000000000000000000000000000000000..9437b84fbe3b12a527baf445e65de0b4c5b04de5 --- /dev/null +++ b/thirdparty/rr/plugins/productpolicy.pl @@ -0,0 +1,145 @@ +#----------------------------------------------------------- +# productpolicy.pl +# Extract/parse the ControlSet00x\Control\ProductOptions\ProductPolicy value +# +# NOTE: For Vista and 2008 ONLY; the value structure changed with Windows 7 +# +# Change History: +# 20091116 - created +# +# Ref: +# http://www.geoffchappell.com/viewer.htm?doc=studies/windows/km/ntoskrnl/ +# api/ex/slmem/productpolicy.htm&tx=19 +# http://www.geoffchappell.com/viewer.htm?doc=notes/windows/license/ +# install.htm&tx=3,5,6;4 +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package productpolicy; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20091116); + +sub getConfig{return %config} + +sub getShortDescr { + return "Parse ProductPolicy value (Vista & Win2008 ONLY)"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my %prodinfo = (1 => "Ultimate", + 2 => "Home Basic", + 3 => "Home Premium", + 5 => "Home Basic N", + 6 => "Business", + 7 => "Standard", + 8 => "Data Center", + 10 => "Enterprise", + 11 => "Starter", + 12 => "Data Center Core", + 13 => "Standard Core", + 14 => "Enterprise Core", + 15 => "Business N"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + + ::logMsg("Launching productpolicy v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $curr; + eval { + $curr = $root_key->get_subkey("Select")->get_value("Current")->get_data(); + }; + $curr = 1 if ($@); + + my $key; + my $key_path = "ControlSet00".$curr."\\Control\\ProductOptions"; + if ($key = $root_key->get_subkey($key_path)) { + my $prod; + eval { + $prod = $key->get_value("ProductPolicy")->get_data(); + }; + if ($@) { + ::rptMsg("Error getting ProductPolicy value: $@"); + } + else { + my %pol = parseData($prod); + ::rptMsg(""); + ::rptMsg("Note: This plugin applies to Vista and Windows 2008 ONLY."); + ::rptMsg("For a listing of names and values, see:"); + ::rptMsg("http://www.geoffchappell.com/viewer.htm?doc=notes/windows/license/install.htm&tx=3,5,6;4"); + ::rptMsg(""); + foreach my $p (sort keys %pol) { + ::rptMsg($p." - ".$pol{$p}); + } + + if (exists $prodinfo{$pol{"Kernel\-ProductInfo"}}) { + ::rptMsg(""); + ::rptMsg("Kernel\-ProductInfo = ".$prodinfo{$pol{"Kernel\-ProductInfo"}}); + } + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub parseHeader { +# Ref: http://www.geoffchappell.com/viewer.htm?doc=studies/windows/km/ntoskrnl/ +# api/ex/slmem/productpolicy.htm&tx=19,21 + my %h; + my @v = unpack("V*",shift); + $h{size} = $v[0]; + $h{array} = $v[1]; + $h{marker} = $v[2]; + $h{version} = $v[4]; + return %h; +} + +sub parseData { + my $pd = shift; + my %policy; + my $h = substr($pd,0,0x14); + my %hdr = parseHeader($h); + my $total_size = $hdr{size}; + my $cursor = 0x14; + + while ($cursor <= $total_size) { + my @vals = unpack("v4V2", substr($pd,$cursor,0x10)); + my $value = substr($pd,$cursor,$vals[0]); + my $name = substr($value,0x10,$vals[1]); + $name =~ s/\00//g; + + my $data = substr($value,0x10 + $vals[1],$vals[3]); + if ($vals[2] == 4) { +# $data = sprintf "0x%x",unpack("V",$data); + $data = unpack("V",$data); + } + elsif ($vals[2] == 1) { + $data =~ s/\00//g; + } + elsif ($vals[2] == 3) { + $data = unpack("H*",$data); + } + else { + + } + $policy{$name} = $data; + $cursor += $vals[0]; + } + delete $policy{""}; + return %policy; +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/producttype.pl b/thirdparty/rr/plugins/producttype.pl new file mode 100644 index 0000000000000000000000000000000000000000..41b39677b6debb09debdadedf3de584ebf2a9585 --- /dev/null +++ b/thirdparty/rr/plugins/producttype.pl @@ -0,0 +1,88 @@ +#----------------------------------------------------------- +# producttype.pl +# Determine Windows product information +# +# History +# 20100713 - updated reference info, formatting +# 20100325 - renamed to producttype.pl +# +# References +# http://support.microsoft.com/kb/181412 +# http://support.microsoft.com/kb/152078 +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package producttype; +use strict; +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100325); + +sub getConfig{return %config} +sub getShortDescr { + return "Queries System hive for Windows Product info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching producttype v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $prod_key_path = $ccs."\\Control\\ProductOptions"; + if (my $prod_key = $root_key->get_subkey($prod_key_path)) { + ::rptMsg($prod_key_path); + ::rptMsg("LastWrite = ".gmtime($prod_key->get_timestamp())); + ::rptMsg(""); + ::rptMsg("Ref: http://support.microsoft.com/kb/152078"); + ::rptMsg(" http://support.microsoft.com/kb/181412"); + ::rptMsg(""); + my $type; + eval { + $type = $prod_key->get_value("ProductType")->get_data(); + ::rptMsg("ProductType = ".$type); + ::rptMsg("Ref: http://technet.microsoft.com/en-us/library/cc782360%28WS.10%29.aspx"); + ::rptMsg("WinNT indicates a workstation."); + ::rptMsg("ServerNT indicates a standalone server."); + ::rptMsg("LanmanNT indicates a domain controller (pri/backup)."); + }; + ::rptMsg(""); +#----------------------------------------------------------- +# http://technet.microsoft.com/en-us/library/cc784364(WS.10).aspx +# +# http://www.geoffchappell.com/viewer.htm?doc=studies/windows/ +# km/ntoskrnl/api/ex/exinit/productsuite.htm +# +#----------------------------------------------------------- + my $suite; + eval { + $suite = $prod_key->get_value("ProductSuite")->get_data(); + ::rptMsg("ProductSuite = ".$suite); + ::rptMsg("Ref: http://technet.microsoft.com/en-us/library/cc784364%28WS.10%29.aspx"); + }; + } + else { + ::rptMsg($prod_key_path." not found."); + } + } + else { + ::rptMsg("Select key not found."); + } +} +1 \ No newline at end of file diff --git a/thirdparty/rr/plugins/profilelist.pl b/thirdparty/rr/plugins/profilelist.pl new file mode 100644 index 0000000000000000000000000000000000000000..bfeae8a6e70095603aec37b6b4c90274e8d0ccbd --- /dev/null +++ b/thirdparty/rr/plugins/profilelist.pl @@ -0,0 +1,137 @@ +#----------------------------------------------------------- +# profilelist.pl +# Gets ProfileList subkeys and ProfileImagePath value; also +# gets the ProfileLoadTimeHigh and Low values, and translates them +# into a readable time +# +# History: +# 20100219 - updated to gather SpecialAccounts and domain +# user info +# 20080415 - created +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package profilelist; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100219); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get content of ProfileList key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + + my %profiles; + + ::logMsg("Launching profilelist v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\ProfileList"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $path; + eval { + $path = $s->get_value("ProfileImagePath")->get_data(); + }; + + ::rptMsg("Path : ".$path); + ::rptMsg("SID : ".$s->get_name()); + ::rptMsg("LastWrite : ".gmtime($s->get_timestamp())." (UTC)"); + + my $user; + if ($path) { + my @a = split(/\\/,$path); + my $end = scalar @a - 1; + $user = $a[$end]; + $profiles{$s->get_name()} = $user; + } + + my @load; + eval { + $load[0] = $s->get_value("ProfileLoadTimeLow")->get_data(); + $load[1] = $s->get_value("ProfileLoadTimeHigh")->get_data(); + }; + if (@load) { + my $loadtime = ::getTime($load[0],$load[1]); + ::rptMsg("LoadTime : ".gmtime($loadtime)." (UTC)"); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +# The following was added 20100219 + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; + if ($key = $root_key->get_subkey($key_path)) { + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + ::rptMsg("Domain Accounts"); + foreach my $s (@subkeys) { + my $name = $s->get_name(); + next unless ($name =~ m/^S\-1/); + + (exists $profiles{$name}) ? (::rptMsg($name." [".$profiles{$name}."]")) + : (::rptMsg($name)); +# ::rptMsg("LastWrite time: ".gmtime($s->get_timestamp())); +# ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + +# Domain Cache? + eval { + my @cache = $key->get_subkey("DomainCache")->get_list_of_values(); + if (scalar @cache > 0) { + ::rptMsg(""); + ::rptMsg("DomainCache"); + foreach my $d (@cache) { + my $str = sprintf "%-15s %-20s",$d->get_name(),$d->get_data(); + ::rptMsg($str); + } + } + }; + + + } + else { + ::rptMsg($key_path." not found."); + } + + + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/proxysettings.pl b/thirdparty/rr/plugins/proxysettings.pl new file mode 100644 index 0000000000000000000000000000000000000000..d403c487d332679efd0793e1ac5f5c43f66a85ad --- /dev/null +++ b/thirdparty/rr/plugins/proxysettings.pl @@ -0,0 +1,70 @@ +#----------------------------------------------------------- +# proxysettings.pl +# Plugin for Registry Ripper, +# Internet Explorer ProxySettings key parser +# +# Change history +# 20081224 - H. Carvey, updated sorting and printing routine +# +# +# copyright 2008 C. Bentley +#----------------------------------------------------------- +package proxysettings; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081224); + +sub getConfig{return %config} +sub getShortDescr {return "Gets contents of user's Proxy Settings";} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching proxysettings v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ProxySettings"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %proxy; + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + my $type = $v->get_type(); + $data = unpack("V",$data) if ($type == 3); + $proxy{$name} = $data; + } + foreach my $n (sort keys %proxy) { + my $str = sprintf " %-30s %-30s",$n,$proxy{$n}; + ::rptMsg($str); +# ::rptMsg(" ".$v->get_name()." ".$v->get_data()); + } + } + else { + ::rptMsg($key_path." key has no values."); + ::logMsg($key_path." key has no values."); + } + } + else { + ::rptMsg($key_path." hat key not found."); + ::logMsg($key_path." hat key not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/rdphint.pl b/thirdparty/rr/plugins/rdphint.pl new file mode 100644 index 0000000000000000000000000000000000000000..680165812ad118218bb0b9a512b6108fde01d8b0 --- /dev/null +++ b/thirdparty/rr/plugins/rdphint.pl @@ -0,0 +1,61 @@ +#----------------------------------------------------------- +# rdphint.pl - http://www.regripper.net/ +# Gathers servers logged onto via RDP and last successful username +# +# by Brandon Nesbit, Trustwave +#----------------------------------------------------------- +package rdphint; +use strict; + +my %config = (hive => "NTUSER", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090715); + +sub getConfig{return %config} +sub getShortDescr { return "Gets hosts logged onto via RDP and the Domain\\Username";} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching RDPHint v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = 'Software\\Microsoft\\Terminal Server Client\\Servers'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Terminal Server Client\\Servers"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $path; + eval { + $path = $s->get_value("UsernameHint")->get_data(); + }; + ::rptMsg(""); + ::rptMsg("Hostname: ".$s->get_name()); + ::rptMsg("Domain/Username: ".$path); + ::rptMsg("LastWrite: ".gmtime($s->get_timestamp())." (UTC)"); + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/rdpport.pl b/thirdparty/rr/plugins/rdpport.pl new file mode 100644 index 0000000000000000000000000000000000000000..44110d33cb13c416c07ead0465c0599882f90966 --- /dev/null +++ b/thirdparty/rr/plugins/rdpport.pl @@ -0,0 +1,59 @@ +#----------------------------------------------------------- +# rdpport.pl +# Determine the RDP Port used +# +# History +# 20100713 - created +# +# References +# http://support.microsoft.com/kb/306759 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package rdpport; +use strict; +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100713); + +sub getConfig{return %config} +sub getShortDescr { + return "Queries System hive for RDP Port"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my $key; + + ::logMsg("Launching rdpport v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $ccs = $root_key->get_subkey("Select")->get_value("Current")->get_data(); + my $key_path = "ControlSet00".$ccs."\\Control\\Terminal Server\\WinStations\\RDP-Tcp"; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("rdpport v.".$VERSION); + ::rptMsg(""); + my $port; + eval { + $port = $key->get_value("PortNumber")->get_data(); + ::rptMsg("Remote Desktop Listening Port Number = ".$port); + }; + ::rptMsg("Error getting PortNumber: ".$@) if ($@); + + } + else { + ::rptMsg($key_path." not found."); + } +} +1 \ No newline at end of file diff --git a/thirdparty/rr/plugins/realplayer6.pl b/thirdparty/rr/plugins/realplayer6.pl new file mode 100644 index 0000000000000000000000000000000000000000..7ea5913a5f3fa936252bd3c165ade9bb40a8da7d --- /dev/null +++ b/thirdparty/rr/plugins/realplayer6.pl @@ -0,0 +1,79 @@ +#----------------------------------------------------------- +# realplayer6.pl +# Plugin for Registry Ripper +# Get Real Player 6 MostRecentClipsx values +# +# Change history +# +# +# References +# +# Note: LastWrite times on c subkeys will all be the same, +# as each subkey is modified as when a new entry is added +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package realplayer6; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets user's RealPlayer v6 MostRecentClips\(Default) values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching realplayer6 v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + ::rptMsg("Realplayer6 v.".$VERSION); + + my $key_path = "Software\\RealNetworks\\RealPlayer\\6.0\\Preferences"; + my $key = $root_key->get_subkey($key_path); + if ($key) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my %rpkeys; + my $tag = "MostRecentClips"; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + if ($name =~ m/^$tag/) { + my $num = $name; + $num =~ s/$tag//; + $rpkeys{$num}{name} = $name; + $rpkeys{$num}{data} = $s->get_value('')->get_data(); + $rpkeys{$num}{lastwrite} = $s->get_timestamp(); + } + } + foreach my $k (sort keys %rpkeys) { + ::rptMsg("\t".$rpkeys{$k}{name}." -> ".$rpkeys{$k}{data}); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/realvnc.pl b/thirdparty/rr/plugins/realvnc.pl new file mode 100644 index 0000000000000000000000000000000000000000..667766aca4cd98e55101f31874a96a0df7097cd7 --- /dev/null +++ b/thirdparty/rr/plugins/realvnc.pl @@ -0,0 +1,75 @@ +#----------------------------------------------------------- +# realvnc.pl +# Plugin to get RealVNC MRU listings from NTUSER.DAT +# +# Change history +# 20091125 - created +# +# References +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package realvnc; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20091125); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets user's RealVNC MRU listing"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching realvnc v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\RealVNC\\VNCViewer4\\MRU'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %mru; + my @order; + foreach my $v (@vals) { + $mru{$v->get_name()} = $v->get_data(); + } + + if (exists($mru{Order})) { + @order = unpack("C*",$mru{Order}); +# List systems connected to based on Order MRU value + ::rptMsg("*Systems output in \"Order\" sequence"); + foreach my $i (0..scalar(@order) - 1) { + $order[$i] = "0".$order[$i] if ($order[$i] < 10); + ::rptMsg(" ".$order[$i]." -> ".$mru{$order[$i]}); + } + } + else { + ::rptMsg("Could not find Order value."); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/recentdocs.pl b/thirdparty/rr/plugins/recentdocs.pl new file mode 100644 index 0000000000000000000000000000000000000000..78506653763137d1243d8566d40c60980102715d --- /dev/null +++ b/thirdparty/rr/plugins/recentdocs.pl @@ -0,0 +1,161 @@ +#----------------------------------------------------------- +# recentdocs.pl +# Plugin for Registry Ripper +# Parses RecentDocs keys/values in NTUSER.DAT +# +# Change history +# 20100405 - Updated to use Encode::decode to translate strings +# 20090115 - Minor update to keep plugin from printing terminating +# MRUListEx value of 0xFFFFFFFF +# 20080418 - Minor update to address NTUSER.DAT files that have +# MRUList values in this key, rather than MRUListEx +# values +# +# References +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package recentdocs; +use strict; +use Encode; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100405); + +sub getShortDescr { + return "Gets contents of user's RecentDocs key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching recentdocs v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("RecentDocs"); + ::rptMsg("**All values printed in MRUList\\MRUListEx order."); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); +# Get RecentDocs values + my %rdvals = getRDValues($key); + if (%rdvals) { + my $tag; + if (exists $rdvals{"MRUListEx"}) { + $tag = "MRUListEx"; + } + elsif (exists $rdvals{"MRUList"}) { + $tag = "MRUList"; + } + else { + + } + + my @list = split(/,/,$rdvals{$tag}); + foreach my $i (@list) { + ::rptMsg(" ".$i." = ".$rdvals{$i}); + } + ::rptMsg(""); + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg("Error: ".$key_path." has no values."); + } +# Get RecentDocs subkeys' values + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($key_path."\\".$s->get_name()); + ::rptMsg("LastWrite Time ".gmtime($s->get_timestamp())." (UTC)"); + + my %rdvals = getRDValues($s); + if (%rdvals) { + my $tag; + if (exists $rdvals{"MRUListEx"}) { + $tag = "MRUListEx"; + } + elsif (exists $rdvals{"MRUList"}) { + $tag = "MRUList"; + } + else { + + } + + my @list = split(/,/,$rdvals{$tag}); + ::rptMsg($tag." = ".$rdvals{$tag}); + foreach my $i (@list) { + ::rptMsg(" ".$i." = ".$rdvals{$i}); + } + + ::rptMsg(""); + } + else { + ::rptMsg($key_path." has no values."); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + + +sub getRDValues { + my $key = shift; + + my $mru = "MRUList"; + my %rdvals; + + my @vals = $key->get_list_of_values(); + if (scalar @vals > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + if ($name =~ m/^$mru/) { + my @mru; + if ($name eq "MRUList") { + @mru = split(//,$data); + } + elsif ($name eq "MRUListEx") { + @mru = unpack("V*",$data); + } +# Horrible, ugly cludge; the last, terminating value in MRUListEx +# is 0xFFFFFFFF, so we remove it. + pop(@mru); + $rdvals{$name} = join(',',@mru); + } + else { +# New code + $data = decode("ucs-2le", $data); + my $file = (split(/\00/,$data))[0]; +# my $file = (split(/\00\00/,$data))[0]; +# $file =~ s/\00//g; + $rdvals{$name} = $file; + } + } + return %rdvals; + } + else { + return undef; + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/regtime.pl b/thirdparty/rr/plugins/regtime.pl new file mode 100644 index 0000000000000000000000000000000000000000..03510c46d9938a5df83dd52b4b55c01078677165 --- /dev/null +++ b/thirdparty/rr/plugins/regtime.pl @@ -0,0 +1,65 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# regtime.pl +# Plugin for Registry Ripper; traverses through a Registry +# hive file, pulling out keys and their LastWrite times, and +# then listing them in order, sorted by the most recent time +# first - works with any Registry hive file. +# +# Change history +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package regtime; +use strict; + +my %config = (hive => "All", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Dumps entire hive - all keys sorted by LastWrite time"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %regkeys; + +sub pluginmain { + my $class = shift; + my $file = shift; + my $reg = Parse::Win32Registry->new($file); + my $root_key = $reg->get_root_key; + ::logMsg("Launching regtime v.".$VERSION); + + traverse($root_key); + + foreach my $t (reverse sort {$a <=> $b} keys %regkeys) { + foreach my $item (@{$regkeys{$t}}) { + ::rptMsg(gmtime($t)."Z \t".$item); + } + } +} + +sub traverse { + my $key = shift; + my $ts = $key->get_timestamp(); + my $name = $key->as_string(); + $name =~ s/\$\$\$PROTO\.HIV//; + $name = (split(/\[/,$name))[0]; + push(@{$regkeys{$ts}},$name); + foreach my $subkey ($key->get_list_of_subkeys()) { + traverse($subkey); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/regtime_tln.pl b/thirdparty/rr/plugins/regtime_tln.pl new file mode 100644 index 0000000000000000000000000000000000000000..558d7f0eebfc03a647280382a5adf3ee49ff7c6c --- /dev/null +++ b/thirdparty/rr/plugins/regtime_tln.pl @@ -0,0 +1,66 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# regtime.pl +# Plugin for Registry Ripper; traverses through a Registry +# hive file, pulling out keys and their LastWrite times, and +# then listing them in order, sorted by the most recent time +# first - works with any Registry hive file. +# +# Change history +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package regtime_tln; +use strict; + +my %config = (hive => "All", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Dumps entire hive - all keys sorted by LastWrite time"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %regkeys; + +sub pluginmain { + my $class = shift; + my $file = shift; + my $reg = Parse::Win32Registry->new($file); + my $root_key = $reg->get_root_key; + ::logMsg("Launching regtime_tln v.".$VERSION); + + traverse($root_key); + + foreach my $t (reverse sort {$a <=> $b} keys %regkeys) { + foreach my $item (@{$regkeys{$t}}) { + #::rptMsg(gmtime($t)."Z \t".$item); + ::rptMsg($t."|REG|M... ".$item); + } + } +} + +sub traverse { + my $key = shift; + my $ts = $key->get_timestamp(); + my $name = $key->as_string(); + $name =~ s/\$\$\$PROTO\.HIV//; + $name = (split(/\[/,$name))[0]; + push(@{$regkeys{$ts}},$name); + foreach my $subkey ($key->get_list_of_subkeys()) { + traverse($subkey); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/renocide.pl b/thirdparty/rr/plugins/renocide.pl new file mode 100644 index 0000000000000000000000000000000000000000..5f71f922f9651102cec4656f4aa489f0cc2cd5a6 --- /dev/null +++ b/thirdparty/rr/plugins/renocide.pl @@ -0,0 +1,65 @@ +#----------------------------------------------------------- +# renocide.pl +# Plugin to assist in the detection of malware per MMPC +# blog post (References, below) +# +# Change History: +# 20110309 - created +# +# References +# http://www.microsoft.com/security/portal/Threat/Encyclopedia/Entry.aspx?Name=Win32/Renocide +# +# copyright 2011 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package renocide; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20110309); + +sub getConfig{return %config} + +sub getShortDescr { + return "Check for Renocide malware"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching renocide v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\DRM\\amty"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("renocide"); + ::rptMsg($key_path); + ::rptMsg("LastWrite: ".gmtime($key->get_timestamp())); + ::rptMsg(""); + ::rptMst($key_path." found; possible Win32\\Renocide infection."); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + ::rptMsg(sprintf "%-12s %-20s",$v->get_name(),$v->get_data()); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/routes.pl b/thirdparty/rr/plugins/routes.pl new file mode 100644 index 0000000000000000000000000000000000000000..823f097b3ef0180c8695867ba1deb23e35ddb423 --- /dev/null +++ b/thirdparty/rr/plugins/routes.pl @@ -0,0 +1,81 @@ +#----------------------------------------------------------- +# routes.pl +# +# Some malware is known to create persistent routes +# +# Change History: +# 20100817 - created +# +# Ref: +# http://support.microsoft.com/kb/141383 +# http://www.symantec.com/security_response/writeup.jsp?docid= +# 2010-041308-3301-99&tabid=2 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package routes; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100817); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get persistent routes"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching routes v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + + my $sb_path = $ccs."\\Services\\Tcpip\\Parameters\\PersistentRoutes"; + + my $sb; + if ($sb = $root_key->get_subkey($sb_path)) { + ::rptMsg($sb_path); + ::rptMsg("LastWrite: ".gmtime($sb->get_timestamp())); + ::rptMsg(""); + my @vals = $sb->get_list_of_values(); + + if (scalar(@vals) > 0) { + ::rptMsg(sprintf "%-15s %-15s %-15s %-5s","Address","Netmask","Gateway","Metric"); + foreach my $v (@vals) { + my ($addr,$netmask,$gateway,$metric) = split(/,/,$v->get_name(),4); + ::rptMsg(sprintf "%-15s %-15s %-15s %-5s",$addr,$netmask,$gateway,$metric); + } + } + else { + ::rptMsg($sb_path." has no values."); + } + } + else { + ::rptMsg($sb_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/runmru.pl b/thirdparty/rr/plugins/runmru.pl new file mode 100644 index 0000000000000000000000000000000000000000..f18a9ec43446eab93726ca1215b4f534ba5b8aae --- /dev/null +++ b/thirdparty/rr/plugins/runmru.pl @@ -0,0 +1,72 @@ +#----------------------------------------------------------- +# runmru.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# RunMru values +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package runmru; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's RunMRU key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching runmru v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("RunMru"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + my %runvals; + my $mru; + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + $runvals{$v->get_name()} = $v->get_data() unless ($v->get_name() =~ m/^MRUList/i); + $mru = $v->get_data() if ($v->get_name() =~ m/^MRUList/i); + } + ::rptMsg("MRUList = ".$mru); + foreach my $r (sort keys %runvals) { + ::rptMsg($r." ".$runvals{$r}); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/safeboot.pl b/thirdparty/rr/plugins/safeboot.pl new file mode 100644 index 0000000000000000000000000000000000000000..66ee850137ecc77e71c137460fdc78ae56ec147d --- /dev/null +++ b/thirdparty/rr/plugins/safeboot.pl @@ -0,0 +1,104 @@ +#----------------------------------------------------------- +# safeboot.pl +# +# Some malware is known to maintain persistence, even when the system +# is booted to SafeMode by writing entries to the SafeBoot subkeys +# ex: http://www.symantec.com/security_response/writeup.jsp? +# docid=2008-011507-0108-99&tabid=2 +# +# Ref: +# http://support.microsoft.com/kb/315222 +# http://support.microsoft.com/kb/202485/ +# +# copyright 2008-2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package safeboot; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081216); + +sub getConfig{return %config} + +sub getShortDescr { + return "Check SafeBoot entries"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching safeboot v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + + my $sb_path = $ccs."\\Control\\SafeBoot"; + my $sb; + if ($sb = $root_key->get_subkey($sb_path)) { + + my @sks = $sb->get_list_of_subkeys(); + + if (scalar(@sks) > 0) { + + foreach my $s (@sks) { + my $name = $s->get_name(); + my $ts = $s->get_timestamp(); + ::rptMsg($name." [".gmtime($ts)." Z]"); + my %sk; + my @subkeys = $s->get_list_of_subkeys(); + + if (scalar(@subkeys) > 0) { + foreach my $s2 (@subkeys) { + my $str; + my $default; + eval { + $default = $s2->get_value("")->get_data(); + }; + ($@)?($str = $s2->get_name()):($str = $s2->get_name()." (".$default.")"); + push(@{$sk{$s2->get_timestamp()}},$str); + } + + foreach my $t (sort keys %sk) { + ::rptMsg(gmtime($t)." Z"); + foreach my $i (@{$sk{$t}}) { + ::rptMsg(" ".$i); + } + } + ::rptMsg(""); + } + else { + ::rptMsg($name." has no subkeys."); + } + } + } + else { + ::rptMsg($sb_path." has no subkeys."); + } + } + else { + ::rptMsg($sb_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); +# ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/sam b/thirdparty/rr/plugins/sam new file mode 100644 index 0000000000000000000000000000000000000000..84568779ff241e6e26887f0bf9a62f0c300e8548 --- /dev/null +++ b/thirdparty/rr/plugins/sam @@ -0,0 +1,3 @@ +#------------------------------------- +# SAM +samparse \ No newline at end of file diff --git a/thirdparty/rr/plugins/samparse.pl b/thirdparty/rr/plugins/samparse.pl new file mode 100644 index 0000000000000000000000000000000000000000..001857728e13b5a9a07964332cda920642a011ca --- /dev/null +++ b/thirdparty/rr/plugins/samparse.pl @@ -0,0 +1,323 @@ +#----------------------------------------------------------- +# samparse.pl +# Parse the SAM hive file for user/group membership info +# +# Change history: +# 20110303 - Fixed parsing of SID, added check for account type +# Acct type determined based on Dustin Hulburt's "Forensic +# Determination of a User's Logon Status in Windows" +# from 10 Aug 2009 (link below) +# 20100712 - Added References entry +# 20091020 - Added extracting UserPasswordHint value +# 20090413 - Added account creation date +# 20080415 - created +# +# References +# Source available here: http://pogostick.net/~pnh/ntpasswd/ +# http://accessdata.com/downloads/media/Forensic_Determination_Users_Logon_Status.pdf +# +# copyright 2011 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package samparse; +use strict; + +my %config = (hive => "SAM", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20110303); + +sub getConfig{return %config} + +sub getShortDescr { + return "Parse SAM file for user/group mbrshp info"; +} +sub getDescr{} +sub getRefs { + my %refs = ("Well-known SIDs" => "http://support.microsoft.com/kb/243330"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %acb_flags = (0x0001 => "Account Disabled", + 0x0002 => "Home directory required", + 0x0004 => "Password not required", + 0x0008 => "Temporary duplicate account", + 0x0010 => "Normal user account", + 0x0020 => "MNS logon user account", + 0x0040 => "Interdomain trust account", + 0x0080 => "Workstation trust account", + 0x0100 => "Server trust account", + 0x0200 => "Password does not expire", + 0x0400 => "Account auto locked"); + +my %types = (0xbc => "Default Admin User", + 0xd4 => "Custom Limited Acct", + 0xb0 => "Default Guest Acct"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching samparse v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + ::rptMsg(""); +# Get user information + ::rptMsg("User Information"); + ::rptMsg("-" x 25); + my $key_path = 'SAM\\Domains\\Account\\Users'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my @user_list = $key->get_list_of_subkeys(); + if (scalar(@user_list) > 0) { + foreach my $u (@user_list) { + my $rid = $u->get_name(); + my $ts = $u->get_timestamp(); + my $tag = "0000"; + if ($rid =~ m/^$tag/) { + my $v_value = $u->get_value("V"); + my $v = $v_value->get_data(); + my %v_val = parseV($v); + $rid =~ s/^0000//; + $rid = hex($rid); + + my $c_date; + eval { + my $create_path = $key_path."\\Names\\".$v_val{name}; + if (my $create = $root_key->get_subkey($create_path)) { + $c_date = $create->get_timestamp(); + } + }; + + ::rptMsg("Username : ".$v_val{name}." [".$rid."]"); + ::rptMsg("Full Name : ".$v_val{fullname}); + ::rptMsg("User Comment : ".$v_val{comment}); + ::rptMsg("Account Type : ".$v_val{type}); + ::rptMsg("Account Created : ".gmtime($c_date)." Z") if ($c_date > 0); + + my $f_value = $u->get_value("F"); + my $f = $f_value->get_data(); + my %f_val = parseF($f); + + my $lastlogin; + my $pwdreset; + my $pwdfail; + ($f_val{last_login_date} == 0) ? ($lastlogin = "Never") : ($lastlogin = gmtime($f_val{last_login_date})." Z"); + ($f_val{pwd_reset_date} == 0) ? ($pwdreset = "Never") : ($pwdreset = gmtime($f_val{pwd_reset_date})." Z"); + ($f_val{pwd_fail_date} == 0) ? ($pwdfail = "Never") : ($pwdfail = gmtime($f_val{pwd_fail_date})." Z"); + + my $pw_hint; + eval { + $pw_hint = $u->get_value("UserPasswordHint")->get_data(); + $pw_hint =~ s/\00//g; + }; + ::rptMsg("Password Hint : ".$pw_hint) unless ($@); + ::rptMsg("Last Login Date : ".$lastlogin); + ::rptMsg("Pwd Reset Date : ".$pwdreset); + ::rptMsg("Pwd Fail Date : ".$pwdfail); + ::rptMsg("Login Count : ".$f_val{login_count}); + foreach my $flag (keys %acb_flags) { + ::rptMsg(" --> ".$acb_flags{$flag}) if ($f_val{acb_flags} & $flag); + } + ::rptMsg(""); + } + } + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + ::rptMsg("-" x 25); + ::rptMsg("Group Membership Information"); + ::rptMsg("-" x 25); +# Get Group membership information + my $key_path = 'SAM\\Domains\\Builtin\\Aliases'; + if ($key = $root_key->get_subkey($key_path)) { + my %grps; + my @groups = $key->get_list_of_subkeys(); + if (scalar(@groups) > 0) { + foreach my $k (@groups) { + my $name = $k->get_name(); + if ($name =~ m/^0000/) { + $grps{$name}{LastWrite} = $k->get_timestamp(); + $grps{$name}{C_value} = $k->get_value("C")->get_data(); + } + } + + foreach my $k (keys %grps) { + my $name = $k; + $name =~ s/^0000//; + my %c_val = parseC($grps{$k}{C_value}); + ::rptMsg("Group Name : ".$c_val{group_name}." [".$c_val{num_users}."]"); + ::rptMsg("LastWrite : ".gmtime($grps{$k}{LastWrite})." Z"); + ::rptMsg("Group Comment : ".$c_val{comment}); + if ($c_val{num_users} == 0) { + ::rptMsg("Users : None"); + }else { + my %users = parseCUsers($grps{$k}{C_value}); + if (scalar(keys %users) != $c_val{num_users}) { + ::logMsg("parseC function reports ".$c_val{num_users}."; parseCUsers function returned ".(scalar(keys %users))); + } + ::rptMsg("Users :"); + foreach my $u (keys %users) { + ::rptMsg(" ".$u); + } + + } + ::rptMsg(""); + } + ::rptMsg("Analysis Tips:"); + ::rptMsg(" - For well-known SIDs, see http://support.microsoft.com/kb/243330"); + ::rptMsg(" - S-1-5-4 = Interactive"); + ::rptMsg(" - S-1-5-11 = Authenticated Users"); + ::rptMsg(" - Correlate the user SIDs to the output of the ProfileList plugin"); + ::rptMsg(""); + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +sub parseF { + my $f = shift; + my %f_value = (); + my @tv; +# last login date + @tv = unpack("VV",substr($f,8,8)); + $f_value{last_login_date} = ::getTime($tv[0],$tv[1]); +# password reset/acct creation + @tv = unpack("VV",substr($f,24,8)); + $f_value{pwd_reset_date} = ::getTime($tv[0],$tv[1]); +# Account expires + @tv = unpack("VV",substr($f,32,8)); + $f_value{acct_exp_date} = ::getTime($tv[0],$tv[1]); +# Incorrect password + @tv = unpack("VV",substr($f,40,8)); + $f_value{pwd_fail_date} = ::getTime($tv[0],$tv[1]); + $f_value{rid} = unpack("V",substr($f,48,4)); + $f_value{acb_flags} = unpack("v",substr($f,56,2)); + $f_value{failed_count} = unpack("v",substr($f,64,2)); + $f_value{login_count} = unpack("v",substr($f,66,2)); + return %f_value; +} + +sub parseV { + my $v = shift; + my %v_val = (); + my $header = substr($v,0,44); + my @vals = unpack("V*",$header); + $v_val{type} = $types{$vals[1]}; + $v_val{name} = _uniToAscii(substr($v,($vals[3] + 0xCC),$vals[4])); + $v_val{fullname} = _uniToAscii(substr($v,($vals[6] + 0xCC),$vals[7])) if ($vals[7] > 0); + $v_val{comment} = _uniToAscii(substr($v,($vals[9] + 0xCC),$vals[10])) if ($vals[10] > 0); + return %v_val; +} + +sub parseC { + my $cv = $_[0]; + my %c_val = (); + my $header = substr($cv,0,0x34); + my @vals = unpack("V*",$header); + + $c_val{group_name} = _uniToAscii(substr($cv,(0x34 + $vals[4]),$vals[5])); + $c_val{comment} = _uniToAscii(substr($cv,(0x34 + $vals[7]),$vals[8])); + $c_val{num_users} = $vals[12]; + + return %c_val; +} + +sub parseCUsers { + my $cv = $_[0]; + my %members = (); + my $header = substr($cv,0,0x34); + my @vals = unpack("V*",$header); + + my $num = $vals[12]; + + my @users = (); + my $ofs; + if ($num > 0) { + my $count = 0; + foreach my $c (1..$num) { + my $ofs = $vals[10] + 52 + $count; + my $tmp = unpack("V",substr($cv,$ofs,4)); + + if ($tmp == 0x101) { + $ofs++ if (unpack("C",substr($cv,$ofs,1)) == 0); + $members{_translateSID(substr($cv,$ofs,12))} = 1; + $count += 12; + } + elsif ($tmp == 0x501) { + $members{_translateSID(substr($cv,$ofs,28))} = 1; + $count += 28; + } + else { + + } + } + } + return %members; +} + +#--------------------------------------------------------------------- +# _translateSID() +# Translate binary data into a SID +# References: +# http://blogs.msdn.com/oldnewthing/archive/2004/03/15/89753.aspx +# http://support.microsoft.com/kb/286182/ +# http://support.microsoft.com/kb/243330 +#--------------------------------------------------------------------- +sub _translateSID { + my $sid = $_[0]; + my $len = length($sid); + my $revision; + my $dashes; + my $idauth; + if ($len < 12) { +# Is a SID ever less than 12 bytes? + return "SID less than 12 bytes"; + } + elsif ($len == 12) { + $revision = unpack("C",substr($sid,0,1)); + $dashes = unpack("C",substr($sid,1,1)); + $idauth = unpack("H*",substr($sid,2,6)); + $idauth =~ s/^0+//g; + my $sub = unpack("V",substr($sid,8,4)); + return "S-".$revision."-".$idauth."-".$sub; + } + elsif ($len > 12) { + $revision = unpack("C",substr($sid,0,1)); + $dashes = unpack("C",substr($sid,1,1)); + $idauth = unpack("H*",substr($sid,2,6)); + $idauth =~ s/^0+//g; + my @sub = unpack("V4",substr($sid,8,16)); + my $rid = unpack("V",substr($sid,24,4)); + my $s = join('-',@sub); + return "S-".$revision."-".$idauth."-".$s."-".$rid; + } + else { +# Nothing to do + } +} + +#--------------------------------------------------------------------- +# _uniToAscii() +#--------------------------------------------------------------------- +sub _uniToAscii { + my $str = $_[0]; + $str =~ s/\00//g; + return $str; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/schedagent.pl b/thirdparty/rr/plugins/schedagent.pl new file mode 100644 index 0000000000000000000000000000000000000000..a3f0d4012fef2a8c02381af049a8e0312b3cf691 --- /dev/null +++ b/thirdparty/rr/plugins/schedagent.pl @@ -0,0 +1,87 @@ +#----------------------------------------------------------- +# schedagent +# Get contents of SchedulingAgent key from Software hive +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package schedagent; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20100817); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get SchedulingAgent key contents"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching schedagent v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\SchedulingAgent"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my ($oldname,$logpath,$folder,$lastrun,$size); + eval { + $oldname = $key->get_value("OldName")->get_data(); + ::rptMsg("OldName = ".$oldname); + }; + + eval { + $logpath = $key->get_value("LogPath")->get_data(); + ::rptMsg("LogPath = ".$logpath); + }; + + eval { + $size = $key->get_value("MaxLogSizeKB")->get_data(); + ::rptMsg("MaxLogSizeKB = ".$size); + }; + + eval { + $folder = $key->get_value("TasksFolder")->get_data(); + ::rptMsg("TasksFolder = ".$folder); + }; +# + eval { + $lastrun = $key->get_value("LastTaskRun")->get_data(); + ::rptMsg("LastTaskRun = ".parseSystemTime($lastrun)); + ::rptMsg(""); + ::rptMsg("Note: LastTaskRun time is written in local system time, not GMT"); + }; + + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub parseSystemTime { + my ($yr,$mon,$dow,$day,$hr,$min,$sec,$mil) = unpack("v8",$_[0]); + $mon = "0".$mon unless ($mon =~ /^\d\d$/); + $day = "0".$day unless ($day =~ /^\d\d$/); + $hr = "0".$hr unless ($hr =~ /^\d\d$/); + $min = "0".$min unless ($min =~ /^\d\d$/); + $sec = "0".$sec unless ($sec =~ /^\d\d$/); + return "$yr-$mon-$day $hr:$min:$sec"; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/secctr.pl b/thirdparty/rr/plugins/secctr.pl new file mode 100644 index 0000000000000000000000000000000000000000..19e53f71bb62dfffb1e319fc822082d690acb289 --- /dev/null +++ b/thirdparty/rr/plugins/secctr.pl @@ -0,0 +1,67 @@ +#----------------------------------------------------------- +# secctr +# Plugin to get data from Security Center keys +# +# Change History: +# 20100310 - created +# +# References: +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package secctr; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100310); + +sub getConfig{return %config} +sub getShortDescr { + return "Get data from Security Center key"; +} +sub getDescr{} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my $infected = 0; + ::logMsg("Launching secctr v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = 'Microsoft\Security Center'; + my $key; + ::rptMsg("secctr"); + ::rptMsg(""); + + if ($key = $root_key->get_subkey($key_path)) { + $infected++; + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $str = sprintf "%-25s 0x%02x",$v->get_name(),$v->get_data(); + ::rptMsg($str); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::rptMsg(""); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/security b/thirdparty/rr/plugins/security new file mode 100644 index 0000000000000000000000000000000000000000..233d63ca8033e9a55a3d4ffbe0f2fd675cc15bd5 --- /dev/null +++ b/thirdparty/rr/plugins/security @@ -0,0 +1,4 @@ +#------------------------------------- +# Security +polacdms +auditpol \ No newline at end of file diff --git a/thirdparty/rr/plugins/services.pl b/thirdparty/rr/plugins/services.pl new file mode 100644 index 0000000000000000000000000000000000000000..a22e24f8fa6f7797b5af4d70050bbbdec2dd7d3c --- /dev/null +++ b/thirdparty/rr/plugins/services.pl @@ -0,0 +1,150 @@ +#----------------------------------------------------------- +# services.pl +# Plugin for Registry Ripper; Access System hive file to get the +# services +# +# Change history +# 20080507 - Added collection of Type and Start values; separated +# data by Services vs. Drivers; created separate plugin +# for Drivers +# 20080505 - Added collection of ImagePath and DisplayName, if avail. +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package services; +#use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080507); + +sub getConfig{return %config} +sub getShortDescr { + return "Lists services/drivers in Services key by LastWrite times"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +# Reference for types and start types: +# http://msdn.microsoft.com/en-us/library/aa394420(VS.85).aspx +my %types = (0x001 => "Kernel driver", + 0x002 => "File system driver", + 0x010 => "Own_Process", + 0x020 => "Share_Process", + 0x100 => "Interactive"); + +my %starts = (0x00 => "Boot Start", + 0x01 => "System Start", + 0x02 => "Auto Start", + 0x03 => "Manual", + 0x04 => "Disabled"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching services v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $s_path = $ccs."\\Services"; + my $svc; + my %svcs; + if ($svc = $root_key->get_subkey($s_path)) { + ::rptMsg($s_path); + ::rptMsg(getShortDescr()); + ::rptMsg(""); +# Get all subkeys and sort based on LastWrite times + my @subkeys = $svc->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + + my $type; + eval { + $type = $s->get_value("Type")->get_data(); +# Only look for services; drivers handled in another plugin + if (exists $types{$type}) { + $type = $types{$type}; + } + else { + $type = sprintf "0x%x",$t; + } + }; + + $name = $s->get_name(); + my $display; + eval { + $display = $s->get_value("DisplayName")->get_data(); + }; + + my $image; + eval { + $image = $s->get_value("ImagePath")->get_data(); + }; + + my $start; + eval { + $start = $s->get_value("Start")->get_data(); + if (exists $starts{$start}) { + $start = $starts{$start}; + } + }; + + my $group; + eval { + $group = $s->get_value("Group")->get_data(); + }; + + my $str = $name.";".$display.";".$image.";".$type.";".$start.";".$group; + push(@{$svcs{$s->get_timestamp()}},$str) unless ($str eq ""); + } + + foreach my $t (reverse sort {$a <=> $b} keys %svcs) { + ::rptMsg(gmtime($t)."Z"); + foreach my $item (@{$svcs{$t}}) { + my ($n,$d,$i,$t,$s,$g) = split(/;/,$item,6); + ::rptMsg(" Name = ".$n); + ::rptMsg(" Display = ".$d); + ::rptMsg(" ImagePath = ".$i); + ::rptMsg(" Type = ".$t); + ::rptMsg(" Start = ".$s); + ::rptMsg(" Group = ".$g); + ::rptMsg(""); + } + } + + } + else { + ::rptMsg($s_path." has no subkeys."); + ::logMsg("Error: ".$s_path." has no subkeys."); + } + } + else { + ::rptMsg($s_path." not found."); + ::logMsg($s_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/sevenzip.pl b/thirdparty/rr/plugins/sevenzip.pl new file mode 100644 index 0000000000000000000000000000000000000000..cc90d31a168ec71a4190e7127d5b3c4d996a6465 --- /dev/null +++ b/thirdparty/rr/plugins/sevenzip.pl @@ -0,0 +1,83 @@ +#----------------------------------------------------------- +# sevenzip.pl +# Google Toolbar Search History plugin +# +# +# Change history +# 20100218 - created +# +# References +# +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package sevenzip; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100218); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets records of histories from 7-Zip keys"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + my %hist; + ::logMsg("Launching 7-zip v.".$VERSION); + + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\7-Zip'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + + eval { + ::rptMsg(""); + my @arc = $key->get_subkey("Compression")->get_subkey("ArcHistory")->get_list_of_values(); + if (scalar @arc > 0) { + ::rptMsg("Compression\\ArcHistory"); + foreach my $a (@arc) { + ::rptMsg(" ".$a->get_name()." -> ".$a->get_data()); + } + } + }; + ::rptMsg("Error: ".$@) if ($@); + + eval { + ::rptMsg(""); + my @arc = $key->get_subkey("Extraction")->get_subkey("PathHistory")->get_list_of_values(); + if (scalar @arc > 0) { + ::rptMsg("Extraction\\PathHistory"); + foreach my $a (@arc) { + ::rptMsg(" ".$a->get_name()." -> ".$a->get_data()); + } + } + }; + ::rptMsg("Error: ".$@) if ($@); + + + + + + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/sfc.pl b/thirdparty/rr/plugins/sfc.pl new file mode 100644 index 0000000000000000000000000000000000000000..16e829670feeccb7c5f4b38aafe3e92499450b9a --- /dev/null +++ b/thirdparty/rr/plugins/sfc.pl @@ -0,0 +1,107 @@ +#----------------------------------------------------------- +# sfc.pl +# Check SFC settings in the Registry +# +# History +# 20100305 - updated +# +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package sfc; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100305); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get SFC values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching sfc v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("sfc v.".$VERSION); + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + next unless ($name =~ m/^sfc/i); + my $str; + if ($name =~ m/^sfcquota$/i || $name =~ m/^sfcdisable$/i) { + $str = sprintf " %-20s 0x%08x",$name,$v->get_data(); + } + else { + $str = sprintf " %-20s %-20s",$name,$v->get_data(); + } + ::rptMsg($str); + } + + } + else { + ::rptMsg($key_path." key has no values."); + } + } + else { + ::rptMsg($key_path." key not found."); + ::logMsg($key_path." key not found."); + } + ::rptMsg(""); +# According to http://support.microsoft.com/kb/222193, sfc* values in this key, if +# it exists, take precedence over and are copied into the values within the Winlogon +# key; see also http://support.microsoft.com/kb/222473/ + my $key_path = "Policies\\Microsoft\\Windows NT\\Windows File Protection"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + next unless ($name =~ m/^sfc/i); + my $str; + if ($name =~ m/^sfcquota$/i || $name =~ m/^sfcdisable$/i) { + $str = sprintf " %-20s 0x%08x",$name,$v->get_data(); + } + else { + $str = sprintf " %-20s %-20s",$name,$v->get_data(); + } + ::rptMsg($str); + } + + } + else { + ::rptMsg($key_path." key has no values."); + } + } + else { + ::rptMsg($key_path." key not found."); +# ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/shares.pl b/thirdparty/rr/plugins/shares.pl new file mode 100644 index 0000000000000000000000000000000000000000..e36f4737cbf738eb1f303d3cb470177d9364dee2 --- /dev/null +++ b/thirdparty/rr/plugins/shares.pl @@ -0,0 +1,128 @@ +#----------------------------------------------------------- +# shares.pl +# +# Retrieve information about shares from a System hive file +# +# References: +# http://support.microsoft.com/kb/556023 +# For info about share types, see the Win32_Share WMI class: +# http://msdn.microsoft.com/en-us/library/aa394435(VS.85).aspx +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package shares; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090112); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get list of shares from System hive file"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $root_key; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching shares v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + eval { + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + }; + if ($@) { + ::rptMsg("Problem locating proper controlset: $@"); + return; + } +# First, connect to the Services key; some versions of Windows appear to +# spell the lanmanserver key as "lanmanserver" and others as "LanmanServer" + my $key_path = $ccs."\\Services"; + my $key; + my $tag = "lanmanserver"; + my $lanman = getKeyPath($key_path,$tag); + if ($lanman ne "") { + my $share_path = $key_path."\\".$lanman."\\Shares"; + my $share; + if ($share = $root_key->get_subkey($share_path)) { + my @vals = $share->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + ::rptMsg(" ".$v->get_name()); + my @data = $v->get_data(); + ::rptMsg(" ".$data[2]); + ::rptMsg(" ".$data[4]); + ::rptMsg(" ".$data[5]); + ::rptMsg(""); + } + } + else { + ::rptMsg($share_path." has no values."); + } + } + else { + ::rptMsg($share_path." not found."); + } + } + else { + ::rptMsg($lanman." subkey not found."); + } + +# Determine of the AutoShareServer/Wks values have been set + my $path = $key_path."\\".$lanman; + my $tag = "parameters"; + my $para = getKeyPath($path,$tag); + eval { + if ($key = $root_key->get_subkey($path."\\".$para)) { + my $auto_svr = $key->get_value("AutoShareServer")->get_data(); + ::rptMsg(" AutoShareServer = ".$auto_svr); + } + }; + + eval { + if ($key = $root_key->get_subkey($path."\\".$para)) { + my $auto_wks = $key->get_value("AutoShareWks")->get_data(); + ::rptMsg(" AutoShareWks = ".$auto_wks); + } + }; +} + +# On different versions of Windows, subkeys such as lanmanserver +# and parameters are spelled differently; use this subroutine to get +# the correct spelling of the name of the subkey +# http://support.microsoft.com/kb/288164 +sub getKeyPath { + my $path = $_[0]; + my $tag = $_[1]; + my $subkey; + if (my $key = $root_key->get_subkey($path)) { + my @sk = $key->get_list_of_subkeys(); + foreach my $s (@sk) { + my $name = $s->get_name(); + $subkey = $name if ($name =~ m/^$tag/i); + } + } + return $subkey; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/shellexec.pl b/thirdparty/rr/plugins/shellexec.pl new file mode 100644 index 0000000000000000000000000000000000000000..608bacac02a8468866c5c3dbce747816c07a2482 --- /dev/null +++ b/thirdparty/rr/plugins/shellexec.pl @@ -0,0 +1,118 @@ +#----------------------------------------------------------- +# shellexec +# Get ShellExecuteHooks values from Software hive (based on BHO +# code) +# +# ShellExecuteHooks are DLLs that load as part of the Explorer.exe process, +# and can intercept commands. There are some legitimate applications that +# run as ShellExecuteHooks, but many times, malware (spy-, ad-ware) will +# install here. ShellExecuteHooks allow you to type a URL into the Start->Run +# box and have that URL opened in your browser. For example, in 2001, Michael +# Dunn wrote KBLaunch, a ShellExecuteHook that looked for "?q" in the Run box +# and would open the appropriate MS KB article. +# +# Refs: +# http://support.microsoft.com/kb/914922 +# http://support.microsoft.com/kb/170918 +# http://support.microsoft.com/kb/943460 +# +# History: +# 20081229 - initial creation +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package shellexec; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081229); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets ShellExecuteHooks from Software hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %bhos; + ::logMsg("Launching shellexec v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellExecuteHooks";; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar (@vals) > 0) { + foreach my $s (@vals) { + my $name = $s->get_name(); + next if ($name =~ m/^-/ || $name eq ""); + my $clsid_path = "Classes\\CLSID\\".$name; + my $clsid; + if ($clsid = $root_key->get_subkey($clsid_path)) { + my $class; + my $mod; + my $lastwrite; + + eval { + $class = $clsid->get_value("")->get_data(); + $bhos{$name}{class} = $class; + }; + if ($@) { + ::logMsg("\tError getting Class name for CLSID\\".$name); + ::logMsg("\t".$@); + } + eval { + $mod = $clsid->get_subkey("InProcServer32")->get_value("")->get_data(); + $bhos{$name}{module} = $mod; + }; + if ($@) { + ::logMsg("\tError getting Module name for CLSID\\".$name); + ::logMsg("\t".$@); + } + eval{ + $lastwrite = $clsid->get_subkey("InProcServer32")->get_timestamp(); + $bhos{$name}{lastwrite} = $lastwrite; + }; + if ($@) { + ::logMsg("\tError getting LastWrite time for CLSID\\".$name); + ::logMsg("\t".$@); + } + + foreach my $b (keys %bhos) { + ::rptMsg($b); + ::rptMsg("\tClass => ".$bhos{$b}{class}); + ::rptMsg("\tModule => ".$bhos{$b}{module}); + ::rptMsg("\tLastWrite => ".gmtime($bhos{$b}{lastwrite})); + ::rptMsg(""); + } + } + else { + ::rptMsg($clsid_path." not found."); + ::rptMsg(""); + ::logMsg($clsid_path." not found."); + } + } + } + else { + ::rptMsg($key_path." has no values. No ShellExecuteHooks installed."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/shellext.pl b/thirdparty/rr/plugins/shellext.pl new file mode 100644 index 0000000000000000000000000000000000000000..8f9994d9d46f606a5ebf2599c05e408fbd530988 --- /dev/null +++ b/thirdparty/rr/plugins/shellext.pl @@ -0,0 +1,96 @@ +#----------------------------------------------------------- +# shellext +# Plugin to get approved shell extensions list from the +# Software hive +# +# This plugin retrieves the list of approved shell extensions from +# the Software hive; specifically, the "Shell Extensions\Approved" +# key. Once it has the names (GUID) and data (string) of each value, +# it then goes to the Classes\CLSID\{GUID} key to get the name of/path to +# the associated DLL, if available. It also gets the LastWrite time of the +# Classes\CLSID\{GUID} key. +# +# Analysis of an incident showed that the intruder placed their malware in +# the C:\Windows dir, using the same name as a known valid shell extension. +# When Explorer.exe launches, it reads the list of approved shell extensions, +# then goes to the Classes\CLSID key to get the path to the associated DLL. The +# intruder chose a shell extension that did not have an explicit path, so when +# explorer.exe looked for it, it started in the C:\Windows dir, and never got to +# the legit DLL in the C:\Windows\system32 dir. +# +# References: +# http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx +# +# +# Note: This plugin can take several minutes to run +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package shellext; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100515); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Shell Extensions from Software hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my %bhos; + ::logMsg("Launching shellext v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my %exts; + + my @vals = $key->get_list_of_values(); + if (scalar (@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + $exts{$name}{name} = $v->get_data(); + + my $clsid_path = "Classes\\CLSID\\".$name; + my $clsid; + if ($clsid = $root_key->get_subkey($clsid_path)) { + eval { + $exts{$v->get_name()}{lastwrite} = $clsid->get_timestamp(); + $exts{$v->get_name()}{dll} = $clsid->get_subkey("InProcServer32")->get_value("")->get_data(); + }; + } + } + foreach my $e (keys %exts) { + ::rptMsg($e." ".$exts{$e}{name}); + ::rptMsg(" DLL: ".$exts{$e}{dll}); + ::rptMsg(" Timestamp: ".gmtime($exts{$e}{lastwrite})." Z"); + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/shellfolders.pl b/thirdparty/rr/plugins/shellfolders.pl new file mode 100644 index 0000000000000000000000000000000000000000..42eb461f407ed477408c6677176f237b689db111 --- /dev/null +++ b/thirdparty/rr/plugins/shellfolders.pl @@ -0,0 +1,71 @@ +#----------------------------------------------------------- +# shellfolders.pl +# +# Retrieve the Shell Folders values from user's hive; while +# this may not be important in every instance, it may give the +# examiner indications as to where to look for certain items; +# for example, if the user's "My Documents" folder has been redirected +# as part of configuration changes (corporate policies, etc.). Also, +# this may be important as part of data leakage exams, as XP and Vista +# allow users to drop and drag files to the CD Burner. +# +# References: +# http://support.microsoft.com/kb/279157 +# http://support.microsoft.com/kb/326982 +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package shellfolders; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090115); + +sub getConfig{return %config} + +sub getShortDescr { + return "Retrieve user Shell Folders values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching shellfolders v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $str = sprintf "%-20s %-40s",$v->get_name(),$v->get_data(); + ::rptMsg($str); + } + ::rptMsg(""); + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/shelloverlay.pl b/thirdparty/rr/plugins/shelloverlay.pl new file mode 100644 index 0000000000000000000000000000000000000000..67c46b858f95d0180c830c67c5fb5562a8b614f1 --- /dev/null +++ b/thirdparty/rr/plugins/shelloverlay.pl @@ -0,0 +1,86 @@ +#----------------------------------------------------------- +# shelloverlay +# Get contents of ShellIconOverlayIdentifiers subkeys; sorts data +# based on LastWrite times of subkeys +# +# History +# 20100308 - created +# +# References +# http://msdn.microsoft.com/en-us/library/cc144123%28VS.85%29.aspx +# Coreflood - http://vil.nai.com/vil/content/v_102053.htm +# http://www.secureworks.com/research/threats/coreflood/?threat=coreflood +# +# Analysis Tip: Malware such as Coreflood uses a random subkey name and a +# random CLSID GUID value +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package shelloverlay; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100308); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets ShellIconOverlayIdentifiers values"; +} +sub getDescr{} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching shelloverlay v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my %id; + + my $key_path = 'Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("shelloverlay"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + my $def; + eval { + $def = $s->get_value("")->get_data(); + $name .= " ".$def; + }; + push(@{$id{$s->get_timestamp()}},$name); + } + + foreach my $t (reverse sort {$a <=> $b} keys %id) { + ::rptMsg(gmtime($t)." Z"); + foreach my $item (@{$id{$t}}) { + ::rptMsg(" ".$item); + } + ::rptMsg(""); + } + + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/shutdown.pl b/thirdparty/rr/plugins/shutdown.pl new file mode 100644 index 0000000000000000000000000000000000000000..a63914d5c021d2891e79a353f8b82d9734d349d0 --- /dev/null +++ b/thirdparty/rr/plugins/shutdown.pl @@ -0,0 +1,76 @@ +#----------------------------------------------------------- +# shutdown.pl +# Plugin for Registry Ripper; Access System hive file to get the +# contents of the ShutdownTime value +# +# Change history +# +# +# References +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package shutdown; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets ShutdownTime value from System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching shutdown v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $win_path = $ccs."\\Control\\Windows"; + my $win; + if ($win = $root_key->get_subkey($win_path)) { + ::rptMsg($win_path." key, ShutdownTime value"); + ::rptMsg($win_path); + ::rptMsg("LastWrite Time ".gmtime($win->get_timestamp())." (UTC)"); + my $sd; + if ($sd = $win->get_value("ShutdownTime")->get_data()) { + my @vals = unpack("VV",$sd); + my $shutdown = ::getTime($vals[0],$vals[1]); + ::rptMsg(" ShutdownTime = ".gmtime($shutdown)." (UTC)"); + + } + else { + ::rptMsg("ShutdownTime value not found."); + } + } + else { + ::rptMsg($win_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/shutdowncount.pl b/thirdparty/rr/plugins/shutdowncount.pl new file mode 100644 index 0000000000000000000000000000000000000000..73d649117d9fa812b5c024008afcdcca93575e15 --- /dev/null +++ b/thirdparty/rr/plugins/shutdowncount.pl @@ -0,0 +1,81 @@ +#----------------------------------------------------------- +# shutdowncount.pl +# +# *Value info first seen at: +# http://forensicsfromthesausagefactory.blogspot.com/2008/06/install-dates-and-shutdown-times-found.html +# thanks to DC1743@gmail.com +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package shutdowncount; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080709); + +sub getConfig{return %config} + +sub getShortDescr { + return "Retrieves ShutDownCount value"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching shutdowncount v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::logMsg("Could not find ".$key_path); + return + } + + my $key_path = $ccs."\\Control\\Watchdog\\Display"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ShutdownCount"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $count = 0; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + if ($v->get_name() eq "ShutdownCount") { + $count = 1; + ::rptMsg("ShutdownCount = ".$v->get_data()); + } + } + ::rptMsg("ShutdownCount value not found.") if ($count == 0); + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/skype.pl b/thirdparty/rr/plugins/skype.pl new file mode 100644 index 0000000000000000000000000000000000000000..3c83bc65f15920d688a3d349e20ad3b27a4d7468 --- /dev/null +++ b/thirdparty/rr/plugins/skype.pl @@ -0,0 +1,60 @@ +#----------------------------------------------------------- +# skype.pl +# +# +# History +# 20100713 - created +# +# References +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package skype; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100713); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets data user's Skype key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching acmru v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Skype'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $install; + eval { + $install = $key->get_subkey("Installer")->get_value("DonwloadLastModified")->get_data(); + ::rptMsg("DonwloadLastModified = ".$install); + }; + ::rptMsg("DonwloadLastModified value not found: ".$@) if ($@); + + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/snapshot.pl b/thirdparty/rr/plugins/snapshot.pl new file mode 100644 index 0000000000000000000000000000000000000000..29bf42b93b3022ea4076aa15cdd2d5e3f18564f4 --- /dev/null +++ b/thirdparty/rr/plugins/snapshot.pl @@ -0,0 +1,96 @@ +#----------------------------------------------------------- +# snapshot.pl +# Plugin to check the ActiveX component for the MS Access Snapshot +# Viewer kill bit +# +# Ref: US-CERT Vuln Note #837785, http://www.kb.cert.org/vuls/id/837785 +# +# Note: Look for each GUID key, and check for the Compatibility Flags value; +# if the value is 0x400, the kill bit is set; a vulnerable system is +# indicated by having IE version 6.x, and the kill bits NOT set (IE 7 +# requires user interaction to download the ActiveX component +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package snapshot; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20080725); + +sub getConfig{return %config} + +sub getShortDescr { + return "Check ActiveX comp kill bit; Access Snapshot"; +} +sub getDescr{} +sub getRefs {"US-CERT Vuln Note 837785" => "http://www.kb.cert.org/vuls/id/837785"} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my @guids = ("{F0E42D50-368C-11D0-AD81-00A0C90DC8D9}", + "{F0E42D60-368C-11D0-AD81-00A0C90DC8D9}", + "{F2175210-368C-11D0-AD81-00A0C90DC8D9}"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching snapshot v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Internet Explorer"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("ActiveX Snapshot Vuln"); + ::rptMsg($key_path); + ::rptMsg(""); + my $ver; + eval { + $ver = $key->get_value("Version")->get_data(); + }; + if ($@) { + ::rptMsg("IE Version not found."); + } + else { + ::rptMsg("IE Version = ".$ver) + } + + ::rptMsg(""); + foreach my $guid (@guids) { + my $g; + eval { + $g = $key->get_subkey("ActiveX Compatibility\\".$guid); + }; + if ($@) { + ::rptMsg("$guid not found."); + } + else { + ::rptMsg("GUID: $guid"); + my $flag; + eval { + $flag = $g->get_value("Compatibility Flags")->get_data(); + }; + if ($@) { + ::rptMsg("Compatibility Flags value not found."); + } + else { + my $str = sprintf "Compatibility Flags 0x%x",$flag; + ::rptMsg($str); + } + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/soft_run.pl b/thirdparty/rr/plugins/soft_run.pl new file mode 100644 index 0000000000000000000000000000000000000000..1c5e7a6d526cabba2eb7d3a2954c217a8800f8fc --- /dev/null +++ b/thirdparty/rr/plugins/soft_run.pl @@ -0,0 +1,97 @@ +#----------------------------------------------------------- +# soft_run +# Get contents of Run key from Software hive +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package soft_run; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20080328); + +sub getConfig{return %config} + +sub getShortDescr { + return "Autostart - get Run key contents from Software hive"; +} +sub getDescr{} +sub getRefs { + my %refs = ("Definition of the Run keys in the WinXP Registry" => + "http://support.microsoft.com/kb/314866"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching soft_run v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Run"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my %vals = getKeyValues($key); + if (scalar(keys %vals) > 0) { + foreach my $v (keys %vals) { + ::rptMsg("\t".$v." -> ".$vals{$v}); + } + } + else { + ::rptMsg($key_path." has no values."); + } + + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + ::rptMsg(""); + ::rptMsg($key_path."\\".$s->get_name()); + ::rptMsg("LastWrite Time ".gmtime($s->get_timestamp())." (UTC)"); + my %vals = getKeyValues($s); + foreach my $v (keys %vals) { + ::rptMsg("\t".$v." -> ".$vals{$v}); + } + } + } + else { + ::rptMsg(""); + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} + +sub getKeyValues { + my $key = shift; + my %vals; + + my @vk = $key->get_list_of_values(); + if (scalar(@vk) > 0) { + foreach my $v (@vk) { + next if ($v->get_name() eq "" && $v->get_data() eq ""); + $vals{$v->get_name()} = $v->get_data(); + } + } + else { + + } + return %vals; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/software b/thirdparty/rr/plugins/software new file mode 100644 index 0000000000000000000000000000000000000000..144bfaf466cb66df4214d1e38fdab85c9f04a9a0 --- /dev/null +++ b/thirdparty/rr/plugins/software @@ -0,0 +1,36 @@ +#------------------------------------- +# Software +winver +win_cv +winnt_cv +defbrowser +ie_version +banner +bitbucket +macaddr +cmd_shell +soft_run +networkcards +ssid +appinitdlls +bho +shellexec +imagefile +port_dev +userinit +winlogon +profilelist +specaccts +mrt +svchost +snapshot +sfc +uninstall +installedcomp +shelloverlay +msis +shellexec +apppaths +drwatson +schedagent +kb950582 \ No newline at end of file diff --git a/thirdparty/rr/plugins/specaccts.pl b/thirdparty/rr/plugins/specaccts.pl new file mode 100644 index 0000000000000000000000000000000000000000..4933d865fa6de0e5abd8bc61c4e12af9149b33b5 --- /dev/null +++ b/thirdparty/rr/plugins/specaccts.pl @@ -0,0 +1,68 @@ +#----------------------------------------------------------- +# specaccts.pl +# Gets contents of SpecialAccounts\UserList key +# +# History +# 20100223 - created +# +# References +# http://www.microsoft.com/security/portal/Threat/Encyclopedia/ +# Entry.aspx?Name=Trojan%3AWin32%2FStarter +# +# http://www.microsoft.com/Security/portal/Threat/Encyclopedia/ +# Entry.aspx?Name=TrojanSpy%3AWin32%2FUrsnif.gen!H&ThreatID=-2147343835 +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package specaccts; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100223); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets contents of SpecialAccounts\\UserList key"; +} +sub getDescr{} + +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching specaccts v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\SpecialAccounts\\UserList"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my %apps; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + ::rptMsg(sprintf "%-20s 0x%x",$v->get_name(),$v->get_data()); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/sql_lastconnect.pl b/thirdparty/rr/plugins/sql_lastconnect.pl new file mode 100644 index 0000000000000000000000000000000000000000..fb21951a75eff1d0405e787043306bb657cce2c3 --- /dev/null +++ b/thirdparty/rr/plugins/sql_lastconnect.pl @@ -0,0 +1,66 @@ +#----------------------------------------------------------- +# sql_lastconnect.pl +# +# Per MS, Microsoft Data Access Components (MDAC) clients can attempt +# to use multiple protocols based on a protocol ordering, which is +# listed in the SuperSocketNetLib\ProtocolOrder value. Successful +# connection attempts (for SQL Server 2000) are cached in the LastConnect +# key. +# +# References: +# http://support.microsoft.com/kb/273673/ +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package sql_lastconnect; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090112); + +sub getConfig{return %config} + +sub getShortDescr { + return "MDAC cache of successful connections"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching sql_lastconnect v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\MSSQLServer\\Client\\SuperSocketNetLib\\LastConnect"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("MDAC Cache of successful connections"); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $str = sprintf "%-15s %-25s",$v->get_name(),$v->get_data(); + ::rptMsg($str); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/ssid.pl b/thirdparty/rr/plugins/ssid.pl new file mode 100644 index 0000000000000000000000000000000000000000..1e7714ae5695a968e10ba44ff277239128646c68 --- /dev/null +++ b/thirdparty/rr/plugins/ssid.pl @@ -0,0 +1,183 @@ +#----------------------------------------------------------- +# ssid +# Gets SSID and other info from WZCSVC key +# +# +# Change History: +# 20100301 - Updated References; removed dwCtlFlags being +# printed; minor adjustments to formatting +# 20091102 - added code to parse EAPOL values for SSIDs +# 20090807 - updated code in accordance with WZC_WLAN_CONFIG +# structure +# +# References +# http://msdn.microsoft.com/en-us/library/aa448338.aspx +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package ssid; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100301); + +sub getConfig{return %config} +sub getShortDescr { + return "Get WZCSVC SSID Info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $error; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching ssid v.".$VERSION); +# Get the NetworkCards values + my %nc; + if (%nc = getNetworkCards($hive)) { + + } + else { + ::logMsg("Problem w/ SSIDs, getting NetworkCards: ".$error); + return; + } + + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\WZCSVC\\Parameters\\Interfaces"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("SSID"); + ::rptMsg($key_path); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + if (exists($nc{$name})) { + ::rptMsg("NIC: ".$nc{$name}{descr}); + ::rptMsg("Key LastWrite: ".gmtime($s->get_timestamp())." UTC"); + ::rptMsg(""); + my @vals = $s->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $n = $v->get_name(); + if ($n =~ m/^Static#/) { + my $data = $v->get_data(); +# my $w = unpack("V",substr($data,0x04,0x04)); +# printf "dwCtlFlags = 0x%x\n",$w; + + my $l = unpack("V",substr($data, 0x10, 0x04)); + my $ssid = substr($data,0x14,$l); + + my $tm = uc(unpack("H*",substr($data,0x08,0x06))); + my @t = split(//,$tm); + my $mac = $t[0].$t[1]."-".$t[2].$t[3]."-".$t[4].$t[5]."-".$t[6].$t[7]."-".$t[8].$t[9]."-".$t[10].$t[11]; + + my ($t1,$t2) = unpack("VV",substr($data,0x2B8,8)); + my $t = ::getTime($t1,$t2); + my $str = sprintf gmtime($t)." MAC: %-18s %-8s",$mac,$ssid; + ::rptMsg($str); + } + } + } + else { + ::rptMsg($name." has no values."); + } + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } + +# Now, go to the EAPOL key, locate the appropriate subkeys and parse out +# any available SSIDs +# EAPOL is Extensible Authentication Protocol over LAN + my $key_path = "Microsoft\\EAPOL\\Parameters\\Interfaces"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + if (exists $nc{$name}) { + ::rptMsg("NIC: ".$nc{$name}{descr}); + } + else { + ::rptMsg("NIC: ".$name); + } + ::rptMsg("LastWrite time: ".gmtime($s->get_timestamp())." UTC"); + + my @vals = $s->get_list_of_values(); + my %eapol; + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + $eapol{$v->get_name()} = parseEAPOLData($v->get_data()); + } + foreach my $i (sort {$a <=> $b} keys %eapol) { + my $str = sprintf "%-3d %s",$i,$eapol{$i}; + ::rptMsg($str); + } + } + ::rptMsg(""); + } + } + else { + ::rtpMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub getNetworkCards { + my $hive = shift; + my %nc; + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $service = $s->get_value("ServiceName")->get_data(); + $nc{$service}{descr} = $s->get_value("Description")->get_data(); + $nc{$service}{lastwrite} = $s->get_timestamp(); + } + } + else { + $error = $key_path." has no subkeys."; + } + } + else { + $error = $key_path." not found."; + } + return %nc; +} + +sub parseEAPOLData { + my $data = shift; + my $size = unpack("V",substr($data,0x10,4)); + return substr($data,0x14,$size); +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/startpage.pl b/thirdparty/rr/plugins/startpage.pl new file mode 100644 index 0000000000000000000000000000000000000000..78dcc9e426c3901897dd35c6ae9cb50edf55476c --- /dev/null +++ b/thirdparty/rr/plugins/startpage.pl @@ -0,0 +1,77 @@ +#----------------------------------------------------------- +# startpage.pl +# For Windows 7 +# +# Change history +# 20100330 - created +# +# References +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package startpage; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100330); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's StartPage key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching startpage v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $menu; + my $balloon; + + eval { + my $val = $key->get_value("StartMenu_Start_Time")->get_data(); + my ($t0,$t1) = unpack("VV",$val); + $menu = ::getTime($t0,$t1); + ::rptMsg("StartMenu_Start_Time = ".gmtime($menu)." Z"); + }; + ::rptMsg("Error: ".@$) if (@$); + + eval { + my $val = $key->get_value("StartMenu_Balloon_Time")->get_data(); + my ($t0,$t1) = unpack("VV",$val); + $balloon = ::getTime($t0,$t1); + ::rptMsg("StartMenu_Balloon_Time = ".gmtime($balloon)." Z"); + }; + ::rptMsg("Error: ".@$) if (@$); + + + + + + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/stillimage.pl b/thirdparty/rr/plugins/stillimage.pl new file mode 100644 index 0000000000000000000000000000000000000000..aaf23600e4bf57e8488455bfc761cd056306a18d --- /dev/null +++ b/thirdparty/rr/plugins/stillimage.pl @@ -0,0 +1,112 @@ +#----------------------------------------------------------- +# stillimage.pl +# Parses contents of Enum\USB key for web cam +# +# History +# 20100222 - created +# +# References +# http://msdn.microsoft.com/en-us/library/ms791870.aspx +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package stillimage; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100222); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get info on StillImage devices"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $reg; + +sub pluginmain { + my $class = shift; + my $hive = shift; + $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +::logMsg("Launching stillimage v.".$VERSION); +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::rptMsg($key_path." not found."); + return; + } + + my $key_path = $ccs."\\Control\\Class\\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + ::rptMsg(""); + foreach my $s (@subkeys) { + my $name = $s->get_name(); + next unless ($name =~ m/\d\d/); + ::rptMsg($name); + + eval { + my $desc = $s->get_value("DriverDesc")->get_data(); + ::rptMsg(" ".$desc); + }; + + eval { + my $desc = $s->get_value("MatchingDeviceID")->get_data(); + ::rptMsg(" ".$desc); + }; + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } + +# http://msdn.microsoft.com/en-us/library/ms791870.aspx +# StillImage logging levels + my $key_path = $ccs."\\Control\\StillImage\\Logging"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg("StillImage Logging Level"); + eval { + my $level = $key->get_subkey("STICLI")->get_value("Level")->get_data(); + my $str = sprintf " STICLI Logging Level = 0x%x",$level; + ::rptMsg($str); + }; + ::rptMsg("STICLI Error: ".$@) if ($@); + + eval { + my $level = $key->get_subkey("STIMON")->get_value("Level")->get_data(); + my $str = sprintf " STIMON Logging Level = 0x%x",$level; + ::rptMsg($str); + }; + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/streammru.pl b/thirdparty/rr/plugins/streammru.pl new file mode 100644 index 0000000000000000000000000000000000000000..0276cad0848e01ea9a9747e121fa1fbbec9a4e1a --- /dev/null +++ b/thirdparty/rr/plugins/streammru.pl @@ -0,0 +1,64 @@ +#----------------------------------------------------------- +# streammru.pl +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package streammru; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090205); + +sub getConfig{return %config} + +sub getShortDescr { + return "streammru"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching streammru v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StreamMRU"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg(""); + + my $data = $key->get_value("5")->get_data(); + + my $drive = substr($data, 0x16,4); + ::rptMsg("Drive = ".$drive); + ::rptMsg(""); + + my $size = substr($data, 0x2d, 1); + ::rptMsg("Size of first object: ".unpack("c",$size)." bytes"); + ::rptMsg(""); + + + + + + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/streams.pl b/thirdparty/rr/plugins/streams.pl new file mode 100644 index 0000000000000000000000000000000000000000..e620c033dfa0864f482b24883ed63c096afae667 --- /dev/null +++ b/thirdparty/rr/plugins/streams.pl @@ -0,0 +1,63 @@ +#----------------------------------------------------------- +# streams.pl +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package streams; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081124); + +sub getConfig{return %config} + +sub getShortDescr { + return "Parse Streams and StreamsMRU entries"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching streams v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StreamMRU'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("streamMRU"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $i (0..10) { + my $data = $key->get_value($i)->get_data(); + open(FH,">",$i); + binmode(FH); + print FH $data; + close(FH); + } + } + else { + ::rptMsg($key_path." has no values."); + } + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/svc.pl b/thirdparty/rr/plugins/svc.pl new file mode 100644 index 0000000000000000000000000000000000000000..32332bf723412b6bbd402b339fd62f31eb0693a9 --- /dev/null +++ b/thirdparty/rr/plugins/svc.pl @@ -0,0 +1,149 @@ +#----------------------------------------------------------- +# svc.pl +# Plugin for Registry Ripper; Access System hive file to get the +# services, display short format (hence "svc", shortened version +# of service.pl plugin) +# +# Change history +# 20080610 - created +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package svc; +#use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080610); + +sub getConfig{return %config} +sub getShortDescr { + return "Lists services/drivers in Services key by LastWrite times (short format)"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +# Reference for types and start types: +# http://msdn.microsoft.com/en-us/library/aa394420(VS.85).aspx +my %types = (0x001 => "Kernel driver", + 0x002 => "File system driver", + 0x010 => "Own_Process", + 0x020 => "Share_Process", + 0x100 => "Interactive"); + +my %starts = (0x00 => "Boot Start", + 0x01 => "System Start", + 0x02 => "Auto Start", + 0x03 => "Manual", + 0x04 => "Disabled"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching svc v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $s_path = $ccs."\\Services"; + my $svc; + my %svcs; + if ($svc = $root_key->get_subkey($s_path)) { + ::rptMsg($s_path); + ::rptMsg(getShortDescr()); + ::rptMsg(""); +# Get all subkeys and sort based on LastWrite times + my @subkeys = $svc->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + + my $type; + eval { + $type = $s->get_value("Type")->get_data(); + }; + + $name = $s->get_name(); + my $display; + eval { + $display = $s->get_value("DisplayName")->get_data(); + }; + + my $image; + eval { + $image = $s->get_value("ImagePath")->get_data(); + }; + + my $start; + eval { + $start = $s->get_value("Start")->get_data(); + if (exists $starts{$start}) { + $start = $starts{$start}; + } + }; + + my $object; + eval { + $object = $s->get_value("ObjectName")->get_data(); + }; + next if ($type == 0x001 || $type == 0x002); + my $str = $name.";".$display.";".$image.";".$type.";".$start.";".$object; + push(@{$svcs{$s->get_timestamp()}},$str) unless ($str eq ""); + } + + foreach my $t (reverse sort {$a <=> $b} keys %svcs) { + ::rptMsg(gmtime($t)."Z"); + foreach my $item (@{$svcs{$t}}) { + my ($n,$d,$i,$t,$s,$o) = split(/;/,$item,6); + my $str = " ".$n; + + if ($i eq "") { + if ($d eq "") { + + } + else { + $str = $str." (".$d.")"; + } + } + else { + $str = $str." (".$i.")"; + } + + $str = $str." [".$o."]" unless ($o eq ""); + + ::rptMsg($str); + } + ::rptMsg(""); + } + + } + else { + ::rptMsg($s_path." has no subkeys."); + ::logMsg("Error: ".$s_path." has no subkeys."); + } + } + else { + ::rptMsg($s_path." not found."); + ::logMsg($s_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/svc2.pl b/thirdparty/rr/plugins/svc2.pl new file mode 100644 index 0000000000000000000000000000000000000000..0a1237037100479ca2151125777b9ed1b2b17e39 --- /dev/null +++ b/thirdparty/rr/plugins/svc2.pl @@ -0,0 +1,148 @@ +#----------------------------------------------------------- +# svc2.pl +# Plugin for Registry Ripper; Access System hive file to get the +# services, display short format (hence "svc", shortened version +# of service.pl plugin); outputs info in .csv format +# +# Change history +# 20081129 - created +# +# Ref: +# http://msdn.microsoft.com/en-us/library/aa394073(VS.85).aspx +# +# Analysis Tip: Several services keys have Parameters subkeys that point to +# the ServiceDll value; During intrusions, a service key may be added to +# the system's Registry; using this module, send the output to .csv format +# and sort on column B to get the names to line up +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package svc2; +#use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20081129); + +sub getConfig{return %config} +sub getShortDescr { + return "Lists Services key contents by LastWrite times (CSV)"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +my %types = (0x001 => "Kernel driver", + 0x002 => "File system driver", + 0x004 => "Adapter", + 0x010 => "Own_Process", + 0x020 => "Share_Process", + 0x100 => "Interactive"); + +my %starts = (0x00 => "Boot Start", + 0x01 => "System Start", + 0x02 => "Auto Start", + 0x03 => "Manual", + 0x04 => "Disabled"); + +sub pluginmain { + my $class = shift; + my $hive = shift; +# ::logMsg("Launching svc2 v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $s_path = $ccs."\\Services"; + my $svc; + my %svcs; + if ($svc = $root_key->get_subkey($s_path)) { +# ::rptMsg($s_path); +# ::rptMsg(getShortDescr()); +# ::rptMsg(""); +# Get all subkeys and sort based on LastWrite times + my @subkeys = $svc->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + $name = $s->get_name(); + my $display; + eval { + $display = $s->get_value("DisplayName")->get_data(); +# take commas out of the display name, replace w/ semi-colons + $display =~ s/,/;/g; + }; + + my $type; + eval { + $type = $s->get_value("Type")->get_data(); + $type = $types{$type} if (exists $types{$type}); + + }; + + my $image; + eval { + $image = $s->get_value("ImagePath")->get_data(); + }; + + my $start; + eval { + $start = $s->get_value("Start")->get_data(); + $start = $starts{$start} if (exists $starts{$start}); + }; + + my $object; + eval { + $object = $s->get_value("ObjectName")->get_data(); + }; + + my $str = $name."\|".$display."\|".$image."\|".$type."\|".$start."\|".$object; + push(@{$svcs{$s->get_timestamp()}},$str) unless ($str eq ""); +# Get ServiceDll value if there is one + eval { + my $para = $s->get_subkey("Parameters"); + my $dll = $para->get_value("ServiceDll")->get_data(); + my $str = $name."\\Parameters\|\|".$dll."\|\|\|"; + push(@{$svcs{$para->get_timestamp()}},$str); + }; + + } + + foreach my $t (reverse sort {$a <=> $b} keys %svcs) { +# ::rptMsg(gmtime($t)."Z"); + foreach my $item (@{$svcs{$t}}) { + my ($n,$d,$i,$t2,$s,$o) = split(/\|/,$item,6); +# ::rptMsg($t.",".$n.",".$d.",".$i.",".$t2.",".$s.",".$o); + ::rptMsg(gmtime($t)."Z".",".$n.",".$d.",".$i.",".$t2.",".$s.",".$o); + } + } + } + else { + ::rptMsg($s_path." has no subkeys."); + ::logMsg("Error: ".$s_path." has no subkeys."); + } + } + else { + ::rptMsg($s_path." not found."); + ::logMsg($s_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/svcdll.pl b/thirdparty/rr/plugins/svcdll.pl new file mode 100644 index 0000000000000000000000000000000000000000..3cfbcd2f242d34de1d9028d4a94ce4e08d502d3d --- /dev/null +++ b/thirdparty/rr/plugins/svcdll.pl @@ -0,0 +1,131 @@ +#----------------------------------------------------------- +# svcdll.pl +# +# Change history +# 20091104 - created +# +# Ref: +# http://msdn.microsoft.com/en-us/library/aa394073(VS.85).aspx +# +# Analysis Tip: Several services keys have Parameters subkeys that point to +# the ServiceDll value; During intrusions, a service key may be added to +# the system's Registry; this module provides a quick look, displaying the +# Service names (in malware, sometimes random) and the ServiceDll value, +# sorted based on the LastWrite time of the <service name>\Parameters subkey. +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package svcdll; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20091104); + +sub getConfig{return %config} +sub getShortDescr { + return "Lists Services keys with ServiceDll values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +#my %types = (0x001 => "Kernel driver", +# 0x002 => "File system driver", +# 0x004 => "Adapter", +# 0x010 => "Own_Process", +# 0x020 => "Share_Process", +# 0x100 => "Interactive"); + +#my %starts = (0x00 => "Boot Start", +# 0x01 => "System Start", +# 0x02 => "Auto Start", +# 0x03 => "Manual", +# 0x04 => "Disabled"); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching svcdll v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $s_path = $ccs."\\Services"; + my $svc; + my %svcs; + if ($svc = $root_key->get_subkey($s_path)) { + +# Get all subkeys and sort based on LastWrite times + my @subkeys = $svc->get_list_of_subkeys(); + if (scalar (@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); +# my $display; +# eval { +# $display = $s->get_value("DisplayName")->get_data(); +# }; + +# my $type; +# eval { +# $type = $s->get_value("Type")->get_data(); +# $type = $types{$type} if (exists $types{$type}); +# }; + +# my $image; +# eval { +# $image = $s->get_value("ImagePath")->get_data(); +# }; + +# my $start; +# eval { +# $start = $s->get_value("Start")->get_data(); +# $start = $starts{$start} if (exists $starts{$start}); +# }; + + my $dll; + eval { + $dll = $s->get_subkey("Parameters")->get_value("ServiceDll")->get_data(); + my $str = $name." -> ".$dll; + push(@{$svcs{$s->get_timestamp()}},$str) unless ($str eq ""); + }; + } + + foreach my $t (reverse sort {$a <=> $b} keys %svcs) { + ::rptMsg(gmtime($t)."Z"); + foreach my $item (@{$svcs{$t}}) { + ::rptMsg(" ".$item); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($s_path." has no subkeys."); + ::logMsg("Error: ".$s_path." has no subkeys."); + } + } + else { + ::rptMsg($s_path." not found."); + ::logMsg($s_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/svchost.pl b/thirdparty/rr/plugins/svchost.pl new file mode 100644 index 0000000000000000000000000000000000000000..481d08ca4628f6decb53edf36ed15b08382a12c0 --- /dev/null +++ b/thirdparty/rr/plugins/svchost.pl @@ -0,0 +1,74 @@ +#----------------------------------------------------------- +# svchost +# Plugin to get data from Security Center keys +# +# Change History: +# 20100322 - created +# +# References: +# http://support.microsoft.com/kb/314056 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package svchost; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100322); + +sub getConfig{return %config} +sub getShortDescr { + return "Get entries from SvcHost key"; +} +sub getDescr{} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my $infected = 0; + ::logMsg("Launching secctr v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = 'Microsoft\Windows NT\CurrentVersion\SvcHost'; + my $key; + ::rptMsg("svchost"); + ::rptMsg(""); + + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my @data = $v->get_data(); + my $d; + if (scalar(@data) > 1) { + $d = join(',',@data); + } + else { + $d = $data[0]; + } + my $str = sprintf "%-15s %-55s",$v->get_name(),$d; + ::rptMsg($str); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::rptMsg(""); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/system b/thirdparty/rr/plugins/system new file mode 100644 index 0000000000000000000000000000000000000000..366c10fc62b07d5dc2708c57e702577ad4d959c2 --- /dev/null +++ b/thirdparty/rr/plugins/system @@ -0,0 +1,36 @@ +#------------------------------------- +# System +compname +xpedition +producttype +dllsearch +termserv +rdpport +shutdown +shutdowncount +nolmhash +timezone +disablelastaccess +eventlog +auditfail +crashcontrol +kbdcrash +pagefile +hibernate +mountdev +routes +network +nic_mst2 +nic +nic2 +fw_config +ide +shares +svc2 +svcdll +imagedev +legacy +stillimage +usbdevices +usbstor +devclass \ No newline at end of file diff --git a/thirdparty/rr/plugins/taskman.pl b/thirdparty/rr/plugins/taskman.pl new file mode 100644 index 0000000000000000000000000000000000000000..3a6b212a59db1ef0baa6cde8a6fd3ae3a8c30c75 --- /dev/null +++ b/thirdparty/rr/plugins/taskman.pl @@ -0,0 +1,61 @@ +#----------------------------------------------------------- +# taskman.pl +# Get Taskman value from Winlogon +# +# References +# http://www.geoffchappell.com/viewer.htm?doc=notes/windows/shell/explorer/ +# taskman.htm&tx=3,5-7,12;4&ts=0,19 +# http://technet.microsoft.com/en-us/library/cc957402.aspx +# +# Change History: +# 20091116 - created +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package taskman; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20091116); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets Taskman from HKLM\\..\\Winlogon"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching taskman v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; + if (my $key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + + eval { + ::rptMsg(""); + my $task = $key->get_value("Taskman")->get_data(); + ::rptMsg("Taskman value = ".$task); + }; + if ($@) { + ::rptMsg("Taskman value not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/termcert.pl b/thirdparty/rr/plugins/termcert.pl new file mode 100644 index 0000000000000000000000000000000000000000..81e4b3750549b6a79514bc109304105388046c21 --- /dev/null +++ b/thirdparty/rr/plugins/termcert.pl @@ -0,0 +1,96 @@ +#----------------------------------------------------------- +# termcert.pl +# Plugin for Registry Ripper; +# +# Change history +# 20110316 - created +# +# copyright 2011 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package termcert; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20110316); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Terminal Server certificate"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching termcert v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $ts_path = $ccs."\\Services\\TermService\\Parameters"; + my $ts; + if ($ts = $root_key->get_subkey($ts_path)) { + ::rptMsg($ts_path); + ::rptMsg("LastWrite Time ".gmtime($ts->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $cert; + eval { + $cert = $ts->get_value("Certificate")->get_raw_data(); + + printSector($cert); + }; + ::rptMsg("Certificate value not found.") if ($@); + } + else { + ::rptMsg($ts_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub printSector { + my $data = shift; + my $len = length($data); + my $remaining = $len; + my $i = 0; + + while ($remaining > 0) { + my $seg1 = substr($data,$i * 16,16); + my @str1 = split(//,unpack("H*",$seg1)); + + my @s3; + foreach my $i (0..15) { + $s3[$i] = $str1[$i * 2].$str1[($i * 2) + 1]; + } + + my $h = join(' ',@s3); + my @s1 = unpack("A*",$seg1); + my $s2 = join('',@s1); + $s2 =~ s/\W/\./g; + + ::rptMsg(sprintf "%-50s %-20s",$h,$s2); + $i++; + $remaining -= 16; + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/termserv.pl b/thirdparty/rr/plugins/termserv.pl new file mode 100644 index 0000000000000000000000000000000000000000..010e3aed5e9727f6605660ed1984a6c31c7e0a2f --- /dev/null +++ b/thirdparty/rr/plugins/termserv.pl @@ -0,0 +1,137 @@ +#----------------------------------------------------------- +# termserv.pl +# Plugin for Registry Ripper; +# +# Change history +# 20100713 - Updated to include additional values, based on references +# 20100119 - updated +# 20090727 - created +# +# References +# Change TS listening port number - http://support.microsoft.com/kb/187623 +# Examining TS key - http://support.microsoft.com/kb/243215 +# Win2K8 TS stops listening - http://support.microsoft.com/kb/954398 +# XP/Win2K3 TSAdvertise value - http://support.microsoft.com/kb/281307 +# AllowTSConnections value - http://support.microsoft.com/kb/305608 +# TSEnabled value - http://support.microsoft.com/kb/222992 +# TSUserEnabled value - http://support.microsoft.com/kb/238965 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package termserv; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100713); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets Terminal Server values from System hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching termserv v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $ts_path = $ccs."\\Control\\Terminal Server"; + my $ts; + if ($ts = $root_key->get_subkey($ts_path)) { + ::rptMsg($ts_path); + ::rptMsg("LastWrite Time ".gmtime($ts->get_timestamp())." (UTC)"); + ::rptMsg(""); + ::rptMsg("Reference: http://support.microsoft.com/kb/243215"); + ::rptMsg(""); + + my $ver; + eval { + $ver = $ts->get_value("ProductVersion")->get_data(); + ::rptMsg(" ProductVersion = ".$ver); + }; + ::rptMsg(""); + + my $fdeny; + eval { + $fdeny = $ts->get_value("fDenyTSConnections")->get_data(); + ::rptMsg(" fDenyTSConnections = ".$fdeny); + ::rptMsg(" 1 = connections denied"); + }; + ::rptMsg("fDenyTSConnections value not found.") if ($@); + ::rptMsg(""); + + my $allow; + eval { + $allow = $ts->get_value("AllowTSConnections")->get_data(); + ::rptMsg(" AllowTSConnections = ".$allow); + ::rptMsg(" Ref: http://support.microsoft.com/kb/305608"); + }; + ::rptMsg(""); + + my $ad; + eval { + $ad = $ts->get_value("TSAdvertise")->get_data(); + ::rptMsg(" TSAdvertise = ".$ad); + ::rptMsg(" 0 = disabled, 1 = enabled (advertise Terminal Services)"); + ::rptMsg(" Ref: http://support.microsoft.com/kb/281307"); + }; + ::rptMsg(""); + + my $enabled; + eval { + $enabled = $ts->get_value("TSEnabled")->get_data(); + ::rptMsg(" TSEnabled = ".$enabled); + ::rptMsg(" 0 = disabled, 1 = enabled (Terminal Services enabled)"); + ::rptMsg(" Ref: http://support.microsoft.com/kb/222992"); + }; + ::rptMsg(""); + + my $user; + eval { + $user = $ts->get_value("TSUserEnabled")->get_data(); + ::rptMsg(" TSUserEnabled = ".$user); + ::rptMsg(" 1 = All users logging in are automatically part of the"); + ::rptMsg(" built-in Terminal Server User group. 0 = No one is a"); + ::rptMsg(" member of the built-in group."); + ::rptMsg(" Ref: http://support.microsoft.com/kb/238965"); + }; + ::rptMsg(""); + + my $help; + eval { + $help = $ts->get_value("fAllowToGetHelp")->get_data(); + ::rptMsg(" fAllowToGetHelp = ".$user); + ::rptMsg(" 1 = Users can request assistance from friend or a "); + ::rptMsg(" support professional."); + ::rptMsg(" Ref: http://www.pctools.com/guides/registry/detail/1213/"); + }; + + } + else { + ::rptMsg($ts_path." not found."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/timezone.pl b/thirdparty/rr/plugins/timezone.pl new file mode 100644 index 0000000000000000000000000000000000000000..fa3f38729d1f2c2424676b0658e7883efe9f836c --- /dev/null +++ b/thirdparty/rr/plugins/timezone.pl @@ -0,0 +1,88 @@ +#----------------------------------------------------------- +# timezone.pl +# Plugin for Registry Ripper; Access System hive file to get the +# contents of the TimeZoneInformation key +# +# Change history +# +# +# References +# http://support.microsoft.com/kb/102986 +# http://support.microsoft.com/kb/207563 +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package timezone; +use strict; + +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Get TimeZoneInformation key contents"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching timezone v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +# First thing to do is get the ControlSet00x marked current...this is +# going to be used over and over again in plugins that access the system +# file + my $current; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + my $ccs = "ControlSet00".$current; + my $tz_path = $ccs."\\Control\\TimeZoneInformation"; + my $tz; + if ($tz = $root_key->get_subkey($tz_path)) { + ::rptMsg("TimeZoneInformation key"); + ::rptMsg($tz_path); + ::rptMsg("LastWrite Time ".gmtime($tz->get_timestamp())." (UTC)"); + my %tz_vals; + my @vals = $tz->get_list_of_values(); + if (scalar(@vals) > 0) { + map{$tz_vals{$_->get_name()} = $_->get_data()}(@vals); + + ::rptMsg(" DaylightName -> ".$tz_vals{"DaylightName"}); + ::rptMsg(" StandardName -> ".$tz_vals{"StandardName"}); + + my $bias = $tz_vals{"Bias"}/60; + my $atbias = $tz_vals{"ActiveTimeBias"}/60; + + ::rptMsg(" Bias -> ".$tz_vals{"Bias"}." (".$bias." hours)"); + ::rptMsg(" ActiveTimeBias -> ".$tz_vals{"ActiveTimeBias"}." (".$atbias." hours)"); + + } + else { + ::rptMsg($tz_path." has no values."); + ::logMsg($tz_path." has no values."); + } + } + else { + ::rptMsg($tz_path." could not be found."); + ::logMsg($tz_path." could not be found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/tsclient.pl b/thirdparty/rr/plugins/tsclient.pl new file mode 100644 index 0000000000000000000000000000000000000000..364c17bff0c66fa331393456b50b00141be618ba --- /dev/null +++ b/thirdparty/rr/plugins/tsclient.pl @@ -0,0 +1,72 @@ +#----------------------------------------------------------- +# tsclient.pl +# Plugin for Registry Ripper +# +# Change history +# +# +# References +# http://support.microsoft.com/kb/312169 +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package tsclient; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 0, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Displays contents of user's Terminal Server Client\\Default key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching tsclient v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Terminal Server Client\\Default'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("TSClient"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %mrus; + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/MRU/,$val))[1]; + $mrus{$tag} = $val.":".$data; + } + foreach my $u (sort {$a <=> $b} keys %mrus) { + my ($val,$data) = split(/:/,$mrus{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/typedpaths.pl b/thirdparty/rr/plugins/typedpaths.pl new file mode 100644 index 0000000000000000000000000000000000000000..292f0370b0ad21b7141d01abc23c5ece8fbd28e7 --- /dev/null +++ b/thirdparty/rr/plugins/typedpaths.pl @@ -0,0 +1,69 @@ +#----------------------------------------------------------- +# typedpaths.pl +# For Windows 7, Desktop Address Bar History +# +# Change history +# 20100330 - created +# +# References +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package typedpaths; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100330); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's typedpaths key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching typedpaths v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\TypedPaths"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %paths; + foreach my $v (@vals) { + my $name = $v->get_name(); + $name =~ s/^url//; + my $data = $v->get_data(); + $paths{$name} = $data; + } + foreach my $p (sort {$a <=> $b} keys %paths) { + ::rptMsg(sprintf "%-8s %-30s","url".$p,$paths{$p}); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/typedurls.pl b/thirdparty/rr/plugins/typedurls.pl new file mode 100644 index 0000000000000000000000000000000000000000..fbd6c194e9e28e8745434af7d7f08ac24f8ae237 --- /dev/null +++ b/thirdparty/rr/plugins/typedurls.pl @@ -0,0 +1,87 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# typedurls.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# TypedURLs values +# +# Change history +# +# +# References +# http://support.microsoft.com/kb/157729 +# http://msdn2.microsoft.com/en-us/library/aa908115.aspx +# +# Notes: Reportedly, only the last 20 entries are maintained; +# Also, new entries aren't added to the key until the current +# instance of IE is terminated. +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package typedurls; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + osmask => 22, + version => 20080324); + +sub getConfig{return %config} +sub getShortDescr { + return "Returns contents of user's TypedURLs key."; +} +sub getDescr{} +sub getRefs { + my %refs = ("IESample Registry Settings" => + "http://msdn2.microsoft.com/en-us/library/aa908115.aspx", + "How to clear History entries in IE" => + "http://support.microsoft.com/kb/157729"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching typedurls v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Internet Explorer\\TypedURLs'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("TypedURLs"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %urls; +# Retrieve values and load into a hash for sorting + foreach my $v (@vals) { + my $val = $v->get_name(); + my $data = $v->get_data(); + my $tag = (split(/url/,$val))[1]; + $urls{$tag} = $val.":".$data; + } +# Print sorted content to report file + foreach my $u (sort {$a <=> $b} keys %urls) { + my ($val,$data) = split(/:/,$urls{$u},2); + ::rptMsg(" ".$val." -> ".$data); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/uninstall.pl b/thirdparty/rr/plugins/uninstall.pl new file mode 100644 index 0000000000000000000000000000000000000000..71975fd38844d3deb8e6a32abf8a0bf19ab30a45 --- /dev/null +++ b/thirdparty/rr/plugins/uninstall.pl @@ -0,0 +1,89 @@ +#----------------------------------------------------------- +# uninstall.pl +# Gets contents of Uninstall key from Software hive; sorts +# display names based on key LastWrite time +# +# References: +# http://support.microsoft.com/kb/247501 +# http://support.microsoft.com/kb/314481 +# http://msdn.microsoft.com/en-us/library/ms954376.aspx +# +# Change History: +# 20100116 - Minor updates +# 20090413 - Extract DisplayVersion info +# 20090128 - Added references +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package uninstall; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100116); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets contents of Uninstall key from Software hive"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching uninstall v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = 'Microsoft\\Windows\\CurrentVersion\\Uninstall'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("Uninstall"); + ::rptMsg($key_path); + ::rptMsg(""); + + my %uninst; + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $lastwrite = $s->get_timestamp(); + my $display; + eval { + $display = $s->get_value("DisplayName")->get_data(); + }; + $display = $s->get_name() if ($display eq ""); + + my $ver; + eval { + $ver = $s->get_value("DisplayVersion")->get_data(); + }; + $display .= " v\.".$ver unless ($@); + + push(@{$uninst{$lastwrite}},$display); + } + foreach my $t (reverse sort {$a <=> $b} keys %uninst) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$uninst{$t}}) { + ::rptMsg("\t$item"); + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/unreadmail.pl b/thirdparty/rr/plugins/unreadmail.pl new file mode 100644 index 0000000000000000000000000000000000000000..5f6aadcf6d3ecae5fe04c445bd1c1b60d91f3223 --- /dev/null +++ b/thirdparty/rr/plugins/unreadmail.pl @@ -0,0 +1,89 @@ +#----------------------------------------------------------- +# unreadmail.pl +# +# +# Change history +# 20100218 - created +# +# References +# http://support.microsoft.com/kb/304148 +# http://support.microsoft.com/kb/831403 +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package unreadmail; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100218); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of Unreadmail key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + my %hist; + ::logMsg("Launching unreadmail v.".$VERSION); + + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + eval { + my $e = $key->get_value("MessageExpiryDays")->get_data(); + ::rptMsg("MessageExpiryDays : ".$e); + ::rptMsg(""); + }; + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + ::rptMsg(""); + foreach my $s (@subkeys) { + ::rptMsg($s->get_name()); + ::rptMsg("LastWrite Time ".gmtime($s->get_timestamp())." (UTC)"); + eval { + my $m = $s->get_value("MessageCount")->get_data(); + ::rptMsg(" MessageCount: ".$m); + }; + + eval { + my $a = $s->get_value("Application")->get_data(); + ::rptMsg(" Application : ".$a); + }; + + eval { + my @t = unpack("VV",$s->get_value("TimeStamp")->get_data()); + my $ts = ::getTime($t[0],$t[1]); + ::rptMsg(" TimeStamp : ".gmtime($ts)." (UTC)"); + }; + + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/urlzone.pl b/thirdparty/rr/plugins/urlzone.pl new file mode 100644 index 0000000000000000000000000000000000000000..f48e82411f02d0962962e4eaedda7665a83dec1d --- /dev/null +++ b/thirdparty/rr/plugins/urlzone.pl @@ -0,0 +1,96 @@ +#----------------------------------------------------------- +# /root/bin/plugins/urlzone.pl +# Plugin to detect URLZONE infection +# +# copyright 2009 Stefan Kelm (skelm@bfk.de) +#----------------------------------------------------------- +package urlzone; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090526); + +sub getConfig{return %config} + +sub getShortDescr {return "URLZONE detection";} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { +my $class = shift; +my $hive = shift; +::logMsg("Launching urlzone v.".$VERSION); +my $reg = Parse::Win32Registry->new($hive); +my $root_key = $reg->get_root_key; + +my $key_path = "Microsoft\\Windows\\CurrentVersion\\Internet Settings\\urlzone"; +my $key; +if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($key_path."\\".$s->get_name()); + ::rptMsg("LastWrite Time = ".gmtime($s->get_timestamp())." (UTC)"); + eval { + my @vals = $s->get_list_of_values(); + if (scalar(@vals) > 0) { + my %sns; + foreach my $v (@vals) { + $sns{$v->get_name()} = $v->get_data(); + } + foreach my $i (keys %sns) { + ::rptMsg("\t\t".$i." = ".$sns{$i}); + } + } + else { +# No values + } + }; + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); +# ::logMsg($key_path." not found."); + } + + my $key_path2 = "Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\userinit.exe"; + my $key2; + if ($key2 = $root_key->get_subkey($key_path2)) { + ::rptMsg($key_path2); + ::rptMsg("LastWrite Time ".gmtime($key2->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $dbg; + eval { + $dbg = $key2->get_value("Debugger")->get_data(); + }; + if ($@) { + ::rptMsg("Debugger value not found."); + } + else { + ::rptMsg("Debugger = ".$dbg); + } + ::rptMsg(""); + } + else { + ::rptMsg($key_path2." not found."); +# ::logMsg($key_path2." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/usb.pl b/thirdparty/rr/plugins/usb.pl new file mode 100644 index 0000000000000000000000000000000000000000..2a4c438c7cfa9226ebccacc826c650330bfcb326 --- /dev/null +++ b/thirdparty/rr/plugins/usb.pl @@ -0,0 +1,111 @@ +#----------------------------------------------------------- +# usb +# Similar to usbstor plugin, but prints output in .csv format; +# also checks MountedDevices keys +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package usb; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080825); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get USB subkeys info; csv output"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $reg; + +sub pluginmain { + my $class = shift; + my $hive = shift; + $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::rptMsg($key_path." not found."); + return; + } + + my $name_path = $ccs."\\Control\\ComputerName\\ComputerName"; + my $comp_name; + eval { + $comp_name = $root_key->get_subkey($name_path)->get_value("ComputerName")->get_data(); + }; + $comp_name = "Test" if ($@); + + my $key_path = $ccs."\\Enum\\USB"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $dev_class = $s->get_name(); + my @sk = $s->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $k (@sk) { + my $serial = $k->get_name(); + my $sn_lw = $k->get_timestamp(); + my $str = $comp_name.",".$dev_class.",".$serial.",".$sn_lw; + + my $loc; + eval { + $loc = $k->get_value("LocationInformation")->get_data(); + $str .= ",".$loc; + }; + $str .= ", " if ($@); + + + my $friendly; + eval { + $friendly = $k->get_value("FriendlyName")->get_data(); + $str .= ",".$friendly; + }; + $str .= ", " if ($@); + + my $parent; + eval { + $parent = $k->get_value("ParentIdPrefix")->get_data(); + $str .= ",".$parent; + }; + + + ::rptMsg($str); + } + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/usbdevices.pl b/thirdparty/rr/plugins/usbdevices.pl new file mode 100644 index 0000000000000000000000000000000000000000..27f7ef8a29282c7fb7822181eeeb73d419435c87 --- /dev/null +++ b/thirdparty/rr/plugins/usbdevices.pl @@ -0,0 +1,108 @@ +#----------------------------------------------------------- +# usbdevices.pl +# Parses contents of Enum\USB key for web cam +# +# History +# 20100219 - created +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package usbdevices; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100219); + +sub getConfig{return %config} + +sub getShortDescr { + return "Parses Enum\\USB key for devices"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $reg; + +sub pluginmain { + my $class = shift; + my $hive = shift; + $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; +::logMsg("Launching usbdevices v.".$VERSION); +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::rptMsg($key_path." not found."); + return; + } + + my $key_path = $ccs."\\Enum\\USB"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar @subkeys > 0) { + foreach my $s (@subkeys) { + my @sk = $s->get_list_of_subkeys(); + if (scalar @sk > 0) { + foreach my $s2 (@sk) { + ::rptMsg(""); + eval { + my $desc = $s2->get_value("DeviceDesc")->get_data(); + ::rptMsg($desc." [".$s->get_name()."\\".$s2->get_name()."]"); + }; + + my $str; + eval { + my $class = $s2->get_value("Class")->get_data(); + ::rptMsg(" Class : ".$class); + }; + + eval { + my $serv = $s2->get_value("Service")->get_data(); + ::rptMsg(" Service : ".$serv); + }; + + eval { + my $serv = $s2->get_value("LocationInformation")->get_data(); + ::rptMsg(" Location Information: ".$serv); + }; + + eval { + my $serv = $s2->get_value("Mfg")->get_data(); + ::rptMsg(" Mfg : ".$serv); + }; + +# eval { +# if ($s2->get_value("Class")->get_data() eq "Image") { +# ::rptMsg("Possible webcam at ".$s->get_name()."\\".$s2->get_name()); +# } +# }; +# ::rptMsg("Error: ".$@) if ($@); + } + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/usbstor.pl b/thirdparty/rr/plugins/usbstor.pl new file mode 100644 index 0000000000000000000000000000000000000000..e0223805a459f564115ff8e379e55672bab23889 --- /dev/null +++ b/thirdparty/rr/plugins/usbstor.pl @@ -0,0 +1,91 @@ +#----------------------------------------------------------- +# usbstor +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package usbstor; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080418); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get USBStor key info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching usbstor v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::rptMsg($key_path." not found."); + return; + } + + my $key_path = $ccs."\\Enum\\USBStor"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("USBStor"); + ::rptMsg($key_path); + ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($s->get_name()." [".gmtime($s->get_timestamp())."]"); + + my @sk = $s->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $k (@sk) { + my $serial = $k->get_name(); + ::rptMsg(" S/N: ".$serial." [".gmtime($k->get_timestamp())."]"); + my $friendly; + eval { + $friendly = $k->get_value("FriendlyName")->get_data(); + }; + ::rptMsg(" FriendlyName : ".$friendly) if ($friendly ne ""); + my $parent; + eval { + $parent = $k->get_value("ParentIdPrefix")->get_data(); + }; + ::rptMsg(" ParentIdPrefix: ".$parent) if ($parent ne ""); + } + } + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/usbstor2.pl b/thirdparty/rr/plugins/usbstor2.pl new file mode 100644 index 0000000000000000000000000000000000000000..b62283bb1c64fd1ab7d8d229784784a4f936bdd6 --- /dev/null +++ b/thirdparty/rr/plugins/usbstor2.pl @@ -0,0 +1,134 @@ +#----------------------------------------------------------- +# usbstor2 +# Similar to usbstor plugin, but prints output in .csv format; +# also checks MountedDevices keys +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package usbstor2; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080825); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get USBStor key info; csv output"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $reg; + +sub pluginmain { + my $class = shift; + my $hive = shift; + $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::rptMsg($key_path." not found."); + return; + } + + my $name_path = $ccs."\\Control\\ComputerName\\ComputerName"; + my $comp_name; + eval { + $comp_name = $root_key->get_subkey($name_path)->get_value("ComputerName")->get_data(); + }; + $comp_name = "Test" if ($@); + + my $key_path = $ccs."\\Enum\\USBStor"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $dev_class = $s->get_name(); + my @sk = $s->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $k (@sk) { + my $serial = $k->get_name(); + my $sn_lw = $k->get_timestamp(); + my $str = $comp_name.",".$dev_class.",".$serial.",".$sn_lw; + + my $friendly; + eval { + $friendly = $k->get_value("FriendlyName")->get_data(); + $str .= ",".$friendly; + }; + $str .= ", " if ($@); + + my $parent; + eval { + $parent = $k->get_value("ParentIdPrefix")->get_data(); + $str .= ",".$parent; + + my $dev = checkMountedDevices($parent); + $str .= ",".$dev if ($dev); + + }; + + + ::rptMsg($str); + } + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +sub checkMountedDevices { + my $pip = shift; + my $root_key = $reg->get_root_key; + my $key_path = 'MountedDevices'; + my $key; + my %md; + if ($key = $root_key->get_subkey($key_path)) { + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + next unless ($name =~ m/^\\DosDevices/); + my $data = $v->get_data(); + if (length($data) > 12) { + $data =~ s/\00//g; + return $name if (grep(/$pip/,$data)); + } + } + } + } + else { + return undef; + } + return undef; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/usbstor3.pl b/thirdparty/rr/plugins/usbstor3.pl new file mode 100644 index 0000000000000000000000000000000000000000..52154548187dbd00b09cd25b5c2ff6d9a9b905e7 --- /dev/null +++ b/thirdparty/rr/plugins/usbstor3.pl @@ -0,0 +1,103 @@ +#----------------------------------------------------------- +# usbstor3 +# Collects USBStor information, output in .csv +# +# History +# 20100312 - created +# +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package usbstor3; +use strict; + +my %config = (hive => "System", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100312); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get USBStor key info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching usbstor3 v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + +# Code for System file, getting CurrentControlSet + my $current; + my $ccs; + my $key_path = 'Select'; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + $current = $key->get_value("Current")->get_data(); + $ccs = "ControlSet00".$current; + } + else { + ::rptMsg($key_path." not found."); + return; + } + + my $key_path = $ccs."\\Enum\\USBStor"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { +# ::rptMsg("USBStor"); +# ::rptMsg($key_path); +# ::rptMsg(""); + + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { +# ::rptMsg($s->get_name()." [".gmtime($s->get_timestamp())."]"); + my $name1 = $s->get_name(); + my $time1 = gmtime($s->get_timestamp()); + + my @sk = $s->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $k (@sk) { + my $serial = $k->get_name(); +# ::rptMsg(" S/N: ".$serial." [".gmtime($k->get_timestamp())."]"); + my $str = $name1.",".$time1.",".$serial.",".gmtime($k->get_timestamp()); + + my $friendly; + eval { + $friendly = $k->get_value("FriendlyName")->get_data(); + $str .= ",".$friendly; + }; + $str .= "," if ($@); +# ::rptMsg(" FriendlyName : ".$friendly) if ($friendly ne ""); + my $parent; + eval { + $parent = $k->get_value("ParentIdPrefix")->get_data(); + $str .= ",".$parent; + }; + $str .= "," if ($@); +# ::rptMsg(" ParentIdPrefix: ".$parent) if ($parent ne ""); + ::rptMsg($str); + } + } +# ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/user_run.pl b/thirdparty/rr/plugins/user_run.pl new file mode 100644 index 0000000000000000000000000000000000000000..f982cfde9a346240b13af26525de141cebb37e6f --- /dev/null +++ b/thirdparty/rr/plugins/user_run.pl @@ -0,0 +1,102 @@ +#----------------------------------------------------------- +# user_run +# Get contents of Run key from Software hive +# +# References: +# http://msdn2.microsoft.com/en-us/library/aa376977.aspx +# http://support.microsoft.com/kb/170086 +# +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package user_run; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20080328); + +sub getConfig{return %config} + +sub getShortDescr { + return "Autostart - get Run key contents from NTUSER\.DAT hive"; +} +sub getDescr{} +sub getRefs { + my %refs = ("Definition of the Run keys in the WinXP Registry" => + "http://support.microsoft.com/kb/314866"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching user_run v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my %vals = getKeyValues($key); + if (scalar(keys %vals) > 0) { + foreach my $v (keys %vals) { + ::rptMsg("\t".$v." -> ".$vals{$v}); + } + } + else { + ::rptMsg($key_path." has no values."); + } + + my @sk = $key->get_list_of_subkeys(); + if (scalar(@sk) > 0) { + foreach my $s (@sk) { + ::rptMsg(""); + ::rptMsg($key_path."\\".$s->get_name()); + ::rptMsg("LastWrite Time ".gmtime($s->get_timestamp())." (UTC)"); + my %vals = getKeyValues($s); + foreach my $v (keys %vals) { + ::rptMsg("\t".$v." -> ".$vals{$v}); + } + } + } + else { + ::rptMsg(""); + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} + +sub getKeyValues { + my $key = shift; + my %vals; + + my @vk = $key->get_list_of_values(); + if (scalar(@vk) > 0) { + foreach my $v (@vk) { + next if ($v->get_name() eq "" && $v->get_data() eq ""); + $vals{$v->get_name()} = $v->get_data(); + } + } + else { + + } + return %vals; +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/user_win.pl b/thirdparty/rr/plugins/user_win.pl new file mode 100644 index 0000000000000000000000000000000000000000..107c71d4be0c76e9d00e35acda5f3cc00c27d35c --- /dev/null +++ b/thirdparty/rr/plugins/user_win.pl @@ -0,0 +1,60 @@ +#----------------------------------------------------------- +# user_win.pl +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package user_win; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080415); + +sub getConfig{return %config} + +sub getShortDescr { + return " -- "; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching user_win v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + eval { + my $load = $key->get_value("load")->get_data(); + ::rptMsg("load value = ".$load); + ::rptMsg("*Should be blank; anything listed gets run when the user logs in."); + }; + + eval { + my $run = $key->get_value("run")->get_data(); + ::rptMsg("run value = ".$run); + ::rptMsg("*Should be blank; anything listed gets run when the user logs in."); + }; + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/userassist.pl b/thirdparty/rr/plugins/userassist.pl new file mode 100644 index 0000000000000000000000000000000000000000..d523444e857540a194b4390b828c263ea31d6221 --- /dev/null +++ b/thirdparty/rr/plugins/userassist.pl @@ -0,0 +1,86 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# userassist.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# UserAssist values +# +# Change history +# 20080726 - added reference to help examiner understand Control +# Panel entries found in output +# 20080301 - updated to include run count along with date +# +# +# +# copyright 2008 H. Carvey +#----------------------------------------------------------- +package userassist; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + osmask => 22, + version => 20080726); + +sub getConfig{return %config} +sub getShortDescr { + return "Displays contents of UserAssist Active Desktop key"; +} +sub getDescr{} +sub getRefs {"Description of Control Panel Files in XP" => "http://support.microsoft.com/kb/313808"} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching UserAssist (Active Desktop) v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + my $key_path = 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\'. + '{75048700-EF1F-11D0-9888-006097DEACF9}\\Count'; + my $key; + my %ua; + my $hrzr = "HRZR"; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("UserAssist (Active Desktop)"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $value_name = $v->get_name(); + my $data = $v->get_data(); + if (length($data) == 16) { + my ($session,$count,$val1,$val2) = unpack("V*",$data); + if ($val2 != 0) { + my $time_value = ::getTime($val1,$val2); + if ($value_name =~ m/^$hrzr/) { + $value_name =~ tr/N-ZA-Mn-za-m/A-Za-z/; + } + $count -= 5 if ($count > 5); + push(@{$ua{$time_value}},$value_name." (".$count.")"); + } + } + } + foreach my $t (reverse sort {$a <=> $b} keys %ua) { + ::rptMsg(gmtime($t)." (UTC)"); + foreach my $item (@{$ua{$t}}) { + ::rptMsg("\t$item"); + } + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/userassist2.pl b/thirdparty/rr/plugins/userassist2.pl new file mode 100644 index 0000000000000000000000000000000000000000..010b9899db0f77a7caf3f12fc226703fb81014e1 --- /dev/null +++ b/thirdparty/rr/plugins/userassist2.pl @@ -0,0 +1,125 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# userassist2.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# UserAssist values +# +# Change history +# 20100322 - Added CLSID list reference +# 20100308 - created, based on original userassist.pl plugin +# +# References +# Control Panel Applets - http://support.microsoft.com/kb/313808 +# CLSIDs - http://www.autohotkey.com/docs/misc/CLSID-List.htm +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package userassist2; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100308); + +sub getConfig{return %config} +sub getShortDescr { + return "Displays contents of UserAssist subkeys"; +} +sub getDescr{} +sub getRefs {"Description of Control Panel Files in XP" => "http://support.microsoft.com/kb/313808"} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching userassist2 v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist"; + my $key; + + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("UserAssist"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($s->get_name()); + processKey($s); + ::rptMsg(""); + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub processKey { + my $ua = shift; + + my $key = $ua->get_subkey("Count"); + + my %ua; + my $hrzr = "HRZR"; + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $value_name = $v->get_name(); + my $data = $v->get_data(); + +# Windows XP/2003/Vista/2008 + if (length($data) == 16) { + my ($session,$count,$val1,$val2) = unpack("V*",$data); + if ($val2 != 0) { + my $time_value = ::getTime($val1,$val2); + if ($value_name =~ m/^$hrzr/) { + $value_name =~ tr/N-ZA-Mn-za-m/A-Za-z/; + } + $count -= 5 if ($count > 5); + push(@{$ua{$time_value}},$value_name." (".$count.")"); + } + } +# Windows 7 + elsif (length($data) == 72) { + $value_name =~ tr/N-ZA-Mn-za-m/A-Za-z/; +# if (unpack("V",substr($data,0,4)) == 0) { +# my $count = unpack("V",substr($data,4,4)); +# my @t = unpack("VV",substr($data,60,8)); +# next if ($t[0] == 0 && $t[1] == 0); +# my $time_val = ::getTime($t[0],$t[1]); +# print " .-> ".$time_val."\n"; +# push(@{$ua{$time_val}},$value_name." (".$count.")"); +# } + my $count = unpack("V",substr($data,4,4)); + my @t = unpack("VV",substr($data,60,8)); + next if ($t[0] == 0 && $t[1] == 0); + my $time_val = ::getTime($t[0],$t[1]); + push(@{$ua{$time_val}},$value_name." (".$count.")"); + } + else { +# Nothing else to do + } + } + foreach my $t (reverse sort {$a <=> $b} keys %ua) { + ::rptMsg(gmtime($t)." Z"); + foreach my $i (@{$ua{$t}}) { + ::rptMsg(" ".$i); + } + } + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/userassist_tln.pl b/thirdparty/rr/plugins/userassist_tln.pl new file mode 100644 index 0000000000000000000000000000000000000000..ea87cb37872ebcbec1d7dbd6fa515a237edbfd80 --- /dev/null +++ b/thirdparty/rr/plugins/userassist_tln.pl @@ -0,0 +1,114 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# userassist_tln.pl +# Plugin for Registry Ripper, NTUSER.DAT edition - gets the +# UserAssist values +# +# Change history +# 20110516 - created, modified from userassist2.pl +# 20100322 - Added CLSID list reference +# 20100308 - created, based on original userassist.pl plugin +# +# References +# Control Panel Applets - http://support.microsoft.com/kb/313808 +# CLSIDs - http://www.autohotkey.com/docs/misc/CLSID-List.htm +# +# copyright 2011 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package userassist_tln; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20110516); + +sub getConfig{return %config} +sub getShortDescr { + return "Displays contents of UserAssist subkeys in TLN format"; +} +sub getDescr{} +sub getRefs {"Description of Control Panel Files in XP" => "http://support.microsoft.com/kb/313808"} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching userassist_tln v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist"; + my $key; + + if ($key = $root_key->get_subkey($key_path)) { +# ::rptMsg("UserAssist"); +# ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); +# ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + ::rptMsg($s->get_name()); + processKey($s); + ::rptMsg(""); + } + } + else { + ::logMsg($key_path." has no subkeys."); + } + } + else { + ::logMsg($key_path." not found."); + } +} + +sub processKey { + my $ua = shift; + my $key = $ua->get_subkey("Count"); + my %ua; + my $hrzr = "HRZR"; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $value_name = $v->get_name(); + my $data = $v->get_data(); + +# Windows XP/2003/Vista/2008 + if (length($data) == 16) { + my ($session,$count,$val1,$val2) = unpack("V*",$data); + if ($val2 != 0) { + my $time_value = ::getTime($val1,$val2); + if ($value_name =~ m/^$hrzr/) { + $value_name =~ tr/N-ZA-Mn-za-m/A-Za-z/; + } + $count -= 5 if ($count > 5); + push(@{$ua{$time_value}},$value_name." (".$count.")"); + } + } +# Windows 7 + elsif (length($data) == 72) { + $value_name =~ tr/N-ZA-Mn-za-m/A-Za-z/; + my $count = unpack("V",substr($data,4,4)); + my @t = unpack("VV",substr($data,60,8)); + next if ($t[0] == 0 && $t[1] == 0); + my $time_val = ::getTime($t[0],$t[1]); + push(@{$ua{$time_val}},$value_name." (".$count.")"); + } + else { +# Nothing else to do + } + } + foreach my $t (reverse sort {$a <=> $b} keys %ua) { + foreach my $i (@{$ua{$t}}) { + ::rptMsg($t."|REG|||UserAssist - ".$i); + } + } + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/userinit.pl b/thirdparty/rr/plugins/userinit.pl new file mode 100644 index 0000000000000000000000000000000000000000..b6664b8626a06eb3c1c708765d85e6e35161e82f --- /dev/null +++ b/thirdparty/rr/plugins/userinit.pl @@ -0,0 +1,63 @@ +#----------------------------------------------------------- +# userinit +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package userinit; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 1, + version => 20080328); + +sub getConfig{return %config} + +sub getShortDescr { + return "Gets UserInit value"; +} +sub getDescr{} +sub getRefs { + my %refs = ("My Documents open at startup" => + "http://support.microsoft.com/kb/555294", + "Userinit" => + "http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/regentry/12330.mspx?mfr=true"); + return %refs; +} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching userinit v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my $ui; + eval { + $ui = $key->get_value("Userinit")->get_data(); + ::rptMsg("\tUserinit -> ".$ui); + }; + ::rptMsg("Error: ".$@) if ($@); + ::rptMsg(""); + ::rptMsg("Per references, content should be %SystemDrive%\\system32\\userinit.exe,"); + ::rptMsg(""); + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/userlocsvc.pl b/thirdparty/rr/plugins/userlocsvc.pl new file mode 100644 index 0000000000000000000000000000000000000000..3974a036e1308e1bb025534f4c04d5c9d285790c --- /dev/null +++ b/thirdparty/rr/plugins/userlocsvc.pl @@ -0,0 +1,62 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# userlocsvc.pl +# Get the contents of the Microsoft\User Location Service\Clients key +# from the user's hive +# +# Ref: +# http://support.microsoft.com/kb/196301 +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package userlocsvc; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090411); + +sub getConfig{return %config} +sub getShortDescr { + return "Displays contents of User Location Service\\Client key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching UserLocSvc v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + my $key_path = 'Software\\Microsoft\\User Location Service\\Client'; + my $key; + my %ua; + my $hrzr = "HRZR"; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $str = sprintf "%-15s %-30s",$v->get_name(),$v->get_data(); + ::rptMsg($str) if ($v->get_type() == 1); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/virut.pl b/thirdparty/rr/plugins/virut.pl new file mode 100644 index 0000000000000000000000000000000000000000..eed5fc2a60716d0dee381184c51e251da9caa262 --- /dev/null +++ b/thirdparty/rr/plugins/virut.pl @@ -0,0 +1,66 @@ +#----------------------------------------------------------- +# virut.pl +# Plugin to detect artifacts of a Virut infection +# +# References: +# Symantec: http://www.symantec.com/security_response/ +# writeup.jsp?docid=2009-020411-2802-99&tabid=2 +# +# +# +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package virut; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090218); + +sub getConfig{return %config} + +sub getShortDescr { + return "Detect Virut artifacts"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching virut v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows\\CurrentVersion\\Explorer"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my $update; + eval { + $update = $key->get_value("UpdateHost")->get_data(); + ::rptMsg("UpdateHost value detected! Possible Virut infection!"); + }; + ::rptMsg("UpdateHost value not found.") if ($@); + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + ::rptMsg(""); + ::rptMsg("Also be sure to check the SYSTEM\\ControlSet00n\\Services\\SharedAccess\\"); + ::rptMsg("Parameters\\FirewallPolicy\\DomainProfile\\AuthorizedApplications\\List key"); + ::rptMsg("for exceptions added to the firewall; use the fw_config\.pl plugin."); +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/vista_bitbucket.pl b/thirdparty/rr/plugins/vista_bitbucket.pl new file mode 100644 index 0000000000000000000000000000000000000000..6fa27c55a526302cb57d05b6afcea1bf6f3263ec --- /dev/null +++ b/thirdparty/rr/plugins/vista_bitbucket.pl @@ -0,0 +1,88 @@ +#----------------------------------------------------------- +# vista_bitbucket +# BitBucket settings for Vista $Recylce.bin are maintained on a +# per-user, per-volume basis +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package vista_bitbucket; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 192, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080420); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get BitBucket settings from Vista via NTUSER\.DAT"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching vista_bitbucket v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + ::rptMsg($v->get_name()." : ".$v->get_data()); + } + + } + else { + ::rptMsg($key_path." has no values."); + } + ::rptMsg(""); + + my @vols; + eval { + @vols = $key->get_subkey("Volume")->get_list_of_subkeys(); + }; + if ($@) { + ::rptMsg("Could not access ".$key_path."\\Volume subkey."); + return; + } + + if (scalar(@vols) > 0) { + foreach my $v (@vols) { + ::rptMsg($v->get_name()." [".gmtime($v->get_timestamp())."] (UTC)"); + eval { + ::rptMsg(sprintf " %-15s %-3s","NukeOnDelete",$v->get_value("NukeOnDelete")->get_data()); + }; + + + } + + } + else { + ::rptMsg($key_path."\\Volume key has no subkeys."); + } + + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/vista_comdlg32.pl b/thirdparty/rr/plugins/vista_comdlg32.pl new file mode 100644 index 0000000000000000000000000000000000000000..d20b8fb89d10f0f79e8aac228c93b5cdd8772e75 --- /dev/null +++ b/thirdparty/rr/plugins/vista_comdlg32.pl @@ -0,0 +1,145 @@ +#----------------------------------------------------------- +# vista_comdlg32.pl +# Plugin for Registry Ripper +# +# Change history +# 20090821 - created +# +# References +# +# +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package vista_comdlg32; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090821); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of Vista user's ComDlg32 key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching vista_comdlg32 v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + ::rptMsg("vista_comdlg32 v.".$VERSION); + ::rptMsg("**All values listed in MRU order."); + +# CIDSizeMRU + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\CIDSizeMRU"; + my $key; + my @vals; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg(""); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my %lvmru; + my @mrulist; + @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { +# First, read in all of the values and the data + foreach my $v (@vals) { + $lvmru{$v->get_name()} = $v->get_data(); + } +# Then, remove the MRUList value + if (exists $lvmru{MRUListEx}) { + delete($lvmru{MRUListEx}); + foreach my $m (keys %lvmru) { + my $file = parseStr($lvmru{$m}); + my $str = sprintf "%-4s ".$file,$m; + ::rptMsg(" ".$str); + } + } + else { + ::rptMsg($key_path." does not have an MRUList value."); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); + +# LastVistedPidlMRU + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU"; + my $key; + my @vals; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my %lvmru; + my @mrulist; + @vals = $key->get_list_of_values(); + + if (scalar(@vals) > 0) { +# First, read in all of the values and the data + foreach my $v (@vals) { + $lvmru{$v->get_name()} = $v->get_data(); + } +# Then, remove the MRUList value + if (exists $lvmru{MRUListEx}) { + delete($lvmru{MRUListEx}); + foreach my $m (keys %lvmru) { + my $file = parseStr($lvmru{$m}); + my $str = sprintf "%-4s ".$file,$m; + ::rptMsg(" ".$str); + } + } + else { + ::rptMsg($key_path." does not have an MRUList value."); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } + ::rptMsg(""); + + +} + +sub parseStr { + my $data = $_[0]; + my $temp; + my $tag = 1; + my $ofs = 0; + + while ($tag) { + my $t = substr($data,$ofs,2); + if (unpack("v",$t) == 0x00) { + $tag = 0; + } + else { + $temp .= $t; + $ofs += 2; + } + } + $temp =~ s/\00//g; + return $temp; +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/vista_wireless.pl b/thirdparty/rr/plugins/vista_wireless.pl new file mode 100644 index 0000000000000000000000000000000000000000..f6b74bcf7a8449f06b2f4e2e94233493dae20520 --- /dev/null +++ b/thirdparty/rr/plugins/vista_wireless.pl @@ -0,0 +1,80 @@ +#----------------------------------------------------------- +# vista_wireless +# +# Get Wireless info from Vista systems +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package vista_wireless; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090514); + +sub getConfig{return %config} +sub getShortDescr { + return "Get Vista Wireless Info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); +my $error; + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching vista_wireless v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Profiles"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + my $name = $s->get_name(); + my $lastwrite = $s->get_timestamp(); + + my $nametype; + eval { + $nametype = $s->get_value("NameType")->get_data(); + }; + if ($@) { + + } + else { + if ($nametype == 0x47) { + my $profilename; + my $descr; + eval { + ::rptMsg("LastWrite = ".gmtime($lastwrite)." Z"); + $profilename = $s->get_value("ProfileName")->get_data(); + $descr = $s->get_value("Description")->get_data(); + ::rptMsg(" ".$profilename." [".$descr."]"); + + }; + } + } + + + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/vncviewer.pl b/thirdparty/rr/plugins/vncviewer.pl new file mode 100644 index 0000000000000000000000000000000000000000..82049c93bd748c2eec8d9479b05a8dd6ac337a63 --- /dev/null +++ b/thirdparty/rr/plugins/vncviewer.pl @@ -0,0 +1,68 @@ +#----------------------------------------------------------- +# vncviewer +# +# +#----------------------------------------------------------- +package vncviewer; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080325); + +sub getConfig{return %config} +sub getShortDescr { + return "Get VNCViewer system list"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching vncviewer v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Software\\ORL\\VNCviewer\\MRU"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("VNCViewer\\MRU"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %vnc; + foreach my $v (@vals) { + $vnc{$v->get_name()} = $v->get_data(); + } + my $ind; + if (exists $vnc{'index'}) { + $ind = $vnc{'index'}; + delete $vnc{'index'}; + } + + ::rptMsg("Index = ".$ind); + my @i = split(//,$ind); + foreach my $i (@i) { + ::rptMsg(" ".$i." -> ".$vnc{$i}); + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/wallpaper.pl b/thirdparty/rr/plugins/wallpaper.pl new file mode 100644 index 0000000000000000000000000000000000000000..2d930cb0b1c08abeb88276fa49d70852ca49c19e --- /dev/null +++ b/thirdparty/rr/plugins/wallpaper.pl @@ -0,0 +1,90 @@ +#----------------------------------------------------------- +# wallpaper.pl +# +# Wallpaper MRU +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package wallpaper; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 200800810); + +sub getConfig{return %config} + +sub getShortDescr { + return "Parses Wallpaper MRU Entries"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching wallpaper v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Wallpaper\\MRU"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("wallpaper"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my %wp; + my @mrulist; + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (sort @vals) { + my $name = $v->get_name(); + if ($name =~ m/^\d/) { + my $data = $v->get_data(); + my $str = getStringValue($data); + $wp{$name} = $str; + } + elsif ($name =~ m/^MRUList/) { + @mrulist = unpack("V*",$v->get_data()); + } + else { +# nothing to do + } + } + foreach my $m (@mrulist) { + next if ($m == 0xffffffff); + ::rptMsg($m." -> ".$wp{$m}); + } + } + else { + ::rptMsg($key_path." has no values"); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + +#----------------------------------------------------------- +# getStringValue() - given a binary data type w/ a Unicode +# string at the beginning, delimited by \x00\x00, return an ASCII +# string +#----------------------------------------------------------- +sub getStringValue { + my $bin = shift; + my $str = (split(/\00\00/,$bin,2))[0]; + $str =~ s/\00//g; + return $str; +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/win7_ua.pl b/thirdparty/rr/plugins/win7_ua.pl new file mode 100644 index 0000000000000000000000000000000000000000..be2ea1afa8c083f27f1ee90bcec60918f1b9ad76 --- /dev/null +++ b/thirdparty/rr/plugins/win7_ua.pl @@ -0,0 +1,140 @@ +#----------------------------------------------------------- +# win7_ua.pl +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package win7_ua; +use strict; +my $vignerekey = "BWHQNKTEZYFSLMRGXADUJOPIVC"; +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20090121); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get Win7 UserAssist data"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching win7_ua v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @subkeys = $key->get_list_of_subkeys(); + + if (scalar(@subkeys) > 0) { + foreach my $s (@subkeys) { + print $s->get_name()."\n"; + + my @vals = $s->get_subkey("Count")->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = decrypt_string($v->get_name(),$vignerekey); + my $data = $v->get_data(); + ::rptMsg(" ".$name); + if (length($data) == 72) { + my %vals = parseData($data); + ::rptMsg(" Counter 1 = ".$vals{counter1}); + ::rptMsg(" Counter 2 = ".$vals{counter2}); + ::rptMsg(" Runtime = ".$vals{runtime}." ms"); + ::rptMsg(" Last Run = ".$vals{lastrun}); + ::rptMsg(" MRU = ".$vals{mru}); + } + } + + } + else { + ::rptMsg($key_path."\\".$s->get_name()." has no values."); + } + } + } + else { + ::rptMsg($key_path." has no subkeys."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} +1; + +sub decrypt_string{ +# decrypts a full string of ciphertext, given the ciphertext and the key. +# returns the plaintext string. + my ($ciphertext, $key) = @_; + my $plaintext; + my @plain; + + $key = $key x (length($ciphertext) / length($key) + 1); + + my @cipherletters = split(//,$ciphertext); + foreach my $i (0..(scalar(@cipherletters) - 1)) { +# print "Cipher letter => ".$cipherletters[$i]."\n"; + if ($cipherletters[$i] =~ m/\w/ && !($cipherletters[$i] =~ m/\d/)) { +# print "Decrypting ".$cipherletters[$i]." with ".(substr($key,$i,1))."\n"; + $plain[$i] = decrypt_letter($cipherletters[$i], (substr($key,$i,1))); + } + else { + $plain[$i] = $cipherletters[$i]; + } + } + +# for( my $i=0; $i<length($ciphertext); $i++ ){ +# $plaintext .= decrypt_letter((substr($ciphertext,$i,1)), (substr($key,$i,1))); +# } + $plaintext = join('',@plain); + return $plaintext; +} + +sub decrypt_letter{ +# decrypts a single letter of ciphertext, given the ciphertext +# letter and the key to use for that letter's position. +# The key is the first letter of the row to look in. + my ($cipher, $row) = @_; + my $plain; + my $upper = 0; + $upper = 1 if (ord($cipher) >= 65 && ord($cipher) <= 90); + +# in row n, plaintext is ciphertext - n, mod 26. + $row = ord(lc($row)) - ord('a'); # enable mod 26 + $cipher = ord(lc($cipher)) - ord('a'); # enable mod 26 + $plain = ($cipher - $row) % 26; + $plain = chr($plain + ord('a')); + + $plain = uc($plain) if ($upper == 1); + return $plain; +} + +sub parseData { + my $data = shift; + my %vals; + + $vals{counter1} = unpack("V",substr($data,4,4)); + $vals{counter2} = unpack("V",substr($data,8,4)); + $vals{runtime} = unpack("V",substr($data,12,4)); + my @a = unpack("VV",substr($data,60,8)); + my $t = ::getTime($a[0],$a[1]); + ($t == 0) ? ($vals{lastrun} = 0) : ($vals{lastrun} = gmtime($t)); + + $vals{mru} = unpack("V",substr($data,68,4)); + return %vals; + +} \ No newline at end of file diff --git a/thirdparty/rr/plugins/win_cv.pl b/thirdparty/rr/plugins/win_cv.pl new file mode 100644 index 0000000000000000000000000000000000000000..977eeb7920990489f76201b7e004ef4f74226f63 --- /dev/null +++ b/thirdparty/rr/plugins/win_cv.pl @@ -0,0 +1,85 @@ +#----------------------------------------------------------- +# win_cv.pl +# Get and display the contents of the Windows\CurrentVersion key +# Output sorted based on length of data +# +# Change History: +# 20080609: added translation of InstallDate time +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package win_cv; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090312); + +sub getConfig{return %config} +sub getShortDescr { + return "Get & display the contents of the Windows\\CurrentVersion key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching win_cv v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows\\CurrentVersion"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my %cv; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + my $len = length($data); + next if ($name eq ""); + if ($v->get_type() == 3) { + $data = _translateBinary($data); + } + push(@{$cv{$len}},$name." : ".$data); + } + foreach my $t (sort {$a <=> $b} keys %cv) { + foreach my $item (@{$cv{$t}}) { + ::rptMsg(" $item"); + } + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values"); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + + +sub _translateBinary { + my $str = unpack("H*",$_[0]); + my $len = length($str); + my @nstr = split(//,$str,$len); + my @list = (); + foreach (0..($len/2)) { + push(@list,$nstr[$_*2].$nstr[($_*2)+1]); + } + return join(' ',@list); +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/winlogon.pl b/thirdparty/rr/plugins/winlogon.pl new file mode 100644 index 0000000000000000000000000000000000000000..6808f3e27860bf89c8eb56ded505a2a9b6273848 --- /dev/null +++ b/thirdparty/rr/plugins/winlogon.pl @@ -0,0 +1,98 @@ +#----------------------------------------------------------- +# WinLogon +# Get values from WinLogon key +# +# History +# 20100219 - Updated output to better present some data +# 20080415 - created +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package winlogon; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20100219); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get values from the WinLogon key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching winlogon v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %wl; + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + my $len = length($data); + next if ($name eq ""); + if ($v->get_type() == 3 && $name ne "DCacheUpdate") { + $data = _translateBinary($data); + } + + $data = sprintf "0x%x",$data if ($name eq "SfcQuota"); + if ($name eq "DCacheUpdate") { + my @v = unpack("VV",$data); + $data = gmtime(::getTime($v[0],$v[1])); + } + + push(@{$wl{$len}},$name." = ".$data); + } + + foreach my $t (sort {$a <=> $b} keys %wl) { + foreach my $item (@{$wl{$t}}) { + ::rptMsg(" $item"); + } + } + + ::rptMsg(""); + ::rptMsg("Analysis Tips: The UserInit and Shell values are executed when a user logs on."); + + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} + +sub _translateBinary { + my $str = unpack("H*",$_[0]); + my $len = length($str); + my @nstr = split(//,$str,$len); + my @list = (); + foreach (0..($len/2)) { + push(@list,$nstr[$_*2].$nstr[($_*2)+1]); + } + return join(' ',@list); +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/winlogon_u.pl b/thirdparty/rr/plugins/winlogon_u.pl new file mode 100644 index 0000000000000000000000000000000000000000..f2355efe83974a9a2f8b48bb7e24d4a9e0c7ff1e --- /dev/null +++ b/thirdparty/rr/plugins/winlogon_u.pl @@ -0,0 +1,90 @@ +#----------------------------------------------------------- +# winlogon_u +# Get values from user's WinLogon key +# +# Change History: +# 20091021 - created +# +# References: +# http://support.microsoft.com/kb/119941 +# +# copyright 2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package winlogon_u; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20091021); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get values from the user's WinLogon key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching winlogon_u v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my %wl; + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + my $len = length($data); + next if ($name eq ""); + if ($v->get_type() == 3) { + $data = _translateBinary($data); + } + push(@{$wl{$len}},$name." = ".$data); + } + + foreach my $t (sort {$a <=> $b} keys %wl) { + foreach my $item (@{$wl{$t}}) { + ::rptMsg(" $item"); + } + } + + ::rptMsg(""); + ::rptMsg("Analysis Tip: Existence of RunGrpConv = 1 value may indicate that the"); + ::rptMsg(" system had been infected with Bredolab (Symantec)."); + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +sub _translateBinary { + my $str = unpack("H*",$_[0]); + my $len = length($str); + my @nstr = split(//,$str,$len); + my @list = (); + foreach (0..($len/2)) { + push(@list,$nstr[$_*2].$nstr[($_*2)+1]); + } + return join(' ',@list); +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/winnt_cv.pl b/thirdparty/rr/plugins/winnt_cv.pl new file mode 100644 index 0000000000000000000000000000000000000000..537ced5ca8082ead4cf02bf01992ca241c4fd652 --- /dev/null +++ b/thirdparty/rr/plugins/winnt_cv.pl @@ -0,0 +1,87 @@ +#----------------------------------------------------------- +# winnt_cv.pl +# Get and display the contents of the Windows\CurrentVersion key +# Output sorted based on length of data +# +# Change History: +# 20080609: added translation of InstallDate time +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package winnt_cv; +use strict; + +my %config = (hive => "Software", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080609); + +sub getConfig{return %config} +sub getShortDescr { + return "Get & display the contents of the Windows NT\\CurrentVersion key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching winnt_cv v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Microsoft\\Windows NT\\CurrentVersion"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("WinNT_CV"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + my %cv; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + my $name = $v->get_name(); + my $data = $v->get_data(); + $data = gmtime($data)." (UTC)" if ($name eq "InstallDate"); + my $len = length($data); + next if ($name eq ""); + if ($v->get_type() == 3) { + $data = _translateBinary($data); + } + push(@{$cv{$len}},$name." : ".$data); + } + foreach my $t (sort {$a <=> $b} keys %cv) { + foreach my $item (@{$cv{$t}}) { + ::rptMsg(" $item"); + } + } + } + else { + ::rptMsg($key_path." has no values."); + ::logMsg($key_path." has no values"); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} + + +sub _translateBinary { + my $str = unpack("H*",$_[0]); + my $len = length($str); + my @nstr = split(//,$str,$len); + my @list = (); + foreach (0..($len/2)) { + push(@list,$nstr[$_*2].$nstr[($_*2)+1]); + } + return join(' ',@list); +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/winrar.pl b/thirdparty/rr/plugins/winrar.pl new file mode 100644 index 0000000000000000000000000000000000000000..f66f06ff65910226c35a331391f1636ab53daea9 --- /dev/null +++ b/thirdparty/rr/plugins/winrar.pl @@ -0,0 +1,66 @@ +#----------------------------------------------------------- +# winrar.pl +# Get WinRAR\ArcHistory entries +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package winrar; +use strict; + +my %config = (hive => "NTUSER\.DAT", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20080819); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get WinRAR\\ArcHistory entries"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching winrar v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\WinRAR\\ArcHistory"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("WinRAR"); + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + ::rptMsg(""); + + my %arc; + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + foreach my $v (@vals) { + $arc{$v->get_name()} = $v->get_data(); + } + + foreach (sort keys %arc) { + ::rptMsg($_." -> ".$arc{$_}); + } + + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/winver.pl b/thirdparty/rr/plugins/winver.pl new file mode 100644 index 0000000000000000000000000000000000000000..d59262e5963f9e9be25c6f9445926743413eec48 --- /dev/null +++ b/thirdparty/rr/plugins/winver.pl @@ -0,0 +1,107 @@ +#----------------------------------------------------------- +# winver.pl +# +# copyright 2008-2009 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package winver; +use strict; + +my %config = (hive => "Software", + osmask => 22, + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + version => 20081210); + +sub getConfig{return %config} + +sub getShortDescr { + return "Get Windows version"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching winver v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + + my $key_path = "Microsoft\\Windows NT\\CurrentVersion"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { +# ::rptMsg("{name}"); +# ::rptMsg($key_path); +# ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + + my $prod; + eval { + $prod = $key->get_value("ProductName")->get_data(); + }; + if ($@) { +# ::rptMsg("ProductName value not found."); + } + else { + ::rptMsg("ProductName = ".$prod); + } + + my $csd; + eval { + $csd = $key->get_value("CSDVersion")->get_data(); + }; + if ($@) { +# ::rptMsg("CSDVersion value not found."); + } + else { + ::rptMsg("CSDVersion = ".$csd); + } + + + my $build; + eval { + $build = $key->get_value("BuildName")->get_data(); + }; + if ($@) { +# ::rptMsg("BuildName value not found."); + } + else { + ::rptMsg("BuildName = ".$build); + } + + my $buildex; + eval { + $buildex = $key->get_value("BuildNameEx")->get_data(); + }; + if ($@) { +# ::rptMsg("BuildName value not found."); + } + else { + ::rptMsg("BuildNameEx = ".$buildex); + } + + + my $install; + eval { + $install = $key->get_value("InstallDate")->get_data(); + }; + if ($@) { +# ::rptMsg("InstallDate value not found."); + } + else { + ::rptMsg("InstallDate = ".gmtime($install)); + } + + + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } + +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/winzip.pl b/thirdparty/rr/plugins/winzip.pl new file mode 100644 index 0000000000000000000000000000000000000000..7fa815250bb94c231bf21e664193315dc5640b1e --- /dev/null +++ b/thirdparty/rr/plugins/winzip.pl @@ -0,0 +1,89 @@ +#----------------------------------------------------------- +# WinZip +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +package winzip; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20080325); + +sub getConfig{return %config} +sub getShortDescr { + return "Get WinZip extract and filemenu values"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + ::logMsg("Launching WinZip v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + my $key_path = "Software\\Nico Mak Computing\\WinZip"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg("WinZip"); + ::rptMsg($key_path); + ::rptMsg(""); + my @subkeys = $key->get_list_of_subkeys(); + my %sk; + foreach my $s (@subkeys) { + $sk{$s->get_name()} = $s; + } + + if (exists $sk{'extract'}) { + my $tag = "extract"; + ::rptMsg($key_path."\\extract [".gmtime($sk{'extract'}->get_timestamp)."]"); + my @vals = $sk{'extract'}->get_list_of_values(); + my %ext; + foreach my $v (@vals) { + my $name = $v->get_name(); + my $num = $name; + $num =~ s/^$tag//; + $ext{$num} = $v->get_data(); + } + foreach my $e (sort {$a <=> $b} keys %ext) { + ::rptMsg(" extract".$e." -> ".$ext{$e}); + } + ::rptMsg(""); + } + else { + ::rptMsg("extract key not found."); + } + + if (exists $sk{'filemenu'}) { + my $tag = "filemenu"; + ::rptMsg($key_path."\\filemenu [".gmtime($sk{'extract'}->get_timestamp)."]"); + my @vals = $sk{'filemenu'}->get_list_of_values(); + my %ext; + foreach my $v (@vals) { + my $name = $v->get_name(); + my $num = $name; + $num =~ s/^$tag//; + $ext{$num} = $v->get_data(); + } + foreach my $e (sort {$a <=> $b} keys %ext) { + ::rptMsg(" filemenu".$e." -> ".$ext{$e}); + } + } + else { + ::rptMsg("filemenu key not found."); + } + } + else { + ::rptMsg($key_path." not found."); + ::logMsg($key_path." not found."); + } +} +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/wordwheelquery.pl b/thirdparty/rr/plugins/wordwheelquery.pl new file mode 100644 index 0000000000000000000000000000000000000000..10a2eba1cffed2b673d44660e93eb24064a64b0b --- /dev/null +++ b/thirdparty/rr/plugins/wordwheelquery.pl @@ -0,0 +1,79 @@ +#----------------------------------------------------------- +# wordwheelquery.pl +# For Windows 7 +# +# Change history +# 20100330 - created +# +# References +# http://www.winhelponline.com/blog/clear-file-search-mru-history-windows-7/ +# +# copyright 2010 Quantum Analytics Research, LLC +#----------------------------------------------------------- +package wordwheelquery; +use strict; + +my %config = (hive => "NTUSER\.DAT", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20100330); + +sub getConfig{return %config} +sub getShortDescr { + return "Gets contents of user's WordWheelQuery key"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $ntuser = shift; + ::logMsg("Launching wordwheelquery v.".$VERSION); + my $reg = Parse::Win32Registry->new($ntuser); + my $root_key = $reg->get_root_key; + + my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\WordWheelQuery"; + my $key; + if ($key = $root_key->get_subkey($key_path)) { + ::rptMsg($key_path); + ::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)"); + my @vals = $key->get_list_of_values(); + if (scalar(@vals) > 0) { + my @list; + my %wwq; + foreach my $v (@vals) { + my $name = $v->get_name(); + if ($name eq "MRUListEx") { + @list = unpack("V*",$v->get_data()); + pop(@list) if ($list[scalar(@list) - 1] == 0xffffffff); + } + else { + my $data = $v->get_data(); + $data =~ s/\00//g; + $wwq{$name} = $data; + } + } +# list searches in MRUListEx order + ::rptMsg(""); + ::rptMsg("Searches listed in MRUListEx order"); + ::rptMsg(""); + foreach my $l (@list) { + ::rptMsg(sprintf "%-4d %-30s",$l,$wwq{$l}); + } + } + else { + ::rptMsg($key_path." has no values."); + } + } + else { + ::rptMsg($key_path." not found."); + } +} + +1; \ No newline at end of file diff --git a/thirdparty/rr/plugins/xpedition.pl b/thirdparty/rr/plugins/xpedition.pl new file mode 100644 index 0000000000000000000000000000000000000000..f3a5d35914d4c8e700425768feb78179807a6255 --- /dev/null +++ b/thirdparty/rr/plugins/xpedition.pl @@ -0,0 +1,60 @@ +#----------------------------------------------------------- +# xpedition.pl +# Determine the edition of XP (MediaCenter, TabletPC) +# +# History +# +# References +# http://windowsitpro.com/article/articleid/94531/ +# how-can-a-script-determine-if-windows-xp-tablet-pc-edition-is-installed.html +# http://unasked.com/question/view/id/119610 +# +# copyright 2009 H. Carvey +#----------------------------------------------------------- +package xpedition; +use strict; +my %config = (hive => "System", + hasShortDescr => 1, + hasDescr => 0, + hasRefs => 0, + osmask => 22, + version => 20090727); + +sub getConfig{return %config} +sub getShortDescr { + return "Queries System hive for XP Edition info"; +} +sub getDescr{} +sub getRefs {} +sub getHive {return $config{hive};} +sub getVersion {return $config{version};} + +my $VERSION = getVersion(); + +sub pluginmain { + my $class = shift; + my $hive = shift; + my $key; + my $edition = 0; + + ::logMsg("Launching xpedition v.".$VERSION); + my $reg = Parse::Win32Registry->new($hive); + my $root_key = $reg->get_root_key; + ::rptMsg("xpedition v.".$VERSION); + eval { + $key = $root_key->get_subkey("WPA\\MediaCenter")->get_value("Installed")->get_data(); + if ($key == 1) { + ::rptMsg("MediaCenter Edition"); + $edition = 1; + } + }; + + eval { + $key = $root_key->get_subkey("WPA\\TabletPC")->get_value("Installed")->get_data(); + if ($key == 1) { + ::rptMsg("TabletPC Edition"); + $edition = 1; + } + }; +} +1 \ No newline at end of file diff --git a/thirdparty/rr/rip.exe b/thirdparty/rr/rip.exe new file mode 100644 index 0000000000000000000000000000000000000000..6ecc7fec59702edf1ada8030897db99fdfe27e45 Binary files /dev/null and b/thirdparty/rr/rip.exe differ diff --git a/thirdparty/rr/rip.pl b/thirdparty/rr/rip.pl new file mode 100644 index 0000000000000000000000000000000000000000..6c561436870248d5bb4a9f17da7222abd3c3da70 --- /dev/null +++ b/thirdparty/rr/rip.pl @@ -0,0 +1,292 @@ +#! c:\perl\bin\perl.exe +#------------------------------------------------------------------------- +# Rip - RegRipper, CLI version +# Use this utility to run a plugins file or a single plugin against a Reg +# hive file. +# +# Output goes to STDOUT +# Usage: see "_syntax()" function +# +# Change History +# 20110516 - added -s & -u options for TLN support +# 20090102 - updated code for relative path to plugins dir +# 20080419 - added '-g' switch (experimental) +# 20080412 - added '-c' switch +# +# copyright 2011 Quantum Analytics Research, LLC +#------------------------------------------------------------------------- +use strict; +use Parse::Win32Registry qw(:REG_); +use Getopt::Long; + +# Included to permit compiling via Perl2Exe +#perl2exe_include "Parse/Win32Registry.pm"; +#perl2exe_include "Parse/Win32Registry/Key.pm"; +#perl2exe_include "Parse/Win32Registry/Entry.pm"; +#perl2exe_include "Parse/Win32Registry/Value.pm"; +#perl2exe_include "Parse/Win32Registry/File.pm"; +#perl2exe_include "Parse/Win32Registry/Win95/File.pm"; +#perl2exe_include "Parse/Win32Registry/Win95/Key.pm"; +#perl2exe_include "Encode/Unicode.pm"; + +my %config; +Getopt::Long::Configure("prefix_pattern=(-|\/)"); +GetOptions(\%config,qw(reg|r=s file|f=s csv|c guess|g user|u=s sys|s=s plugin|p=s list|l help|?|h)); + +# Code updated 20090102 +my @path; +my $str = $0; +($^O eq "MSWin32") ? (@path = split(/\\/,$0)) + : (@path = split(/\//,$0)); +$str =~ s/($path[scalar(@path) - 1])//; +my $plugindir = $str."plugins/"; +#print "Plugins Dir = ".$plugindir."\n"; +# End code update +my $VERSION = "20090102"; + +if ($config{help} || !%config) { + _syntax(); + exit; +} + +#------------------------------------------------------------- +# +#------------------------------------------------------------- +if ($config{list}) { + my @plugins; + opendir(DIR,$plugindir) || die "Could not open $plugindir: $!\n"; + @plugins = readdir(DIR); + closedir(DIR); + + my $count = 1; + print "Plugin,Version,Hive,Description\n" if ($config{csv}); + foreach my $p (@plugins) { + next unless ($p =~ m/\.pl$/); + my $pkg = (split(/\./,$p,2))[0]; + $p = $plugindir.$p; + eval { + require $p; + my $hive = $pkg->getHive(); + my $version = $pkg->getVersion(); + my $descr = $pkg->getShortDescr(); + if ($config{csv}) { + print $pkg.",".$version.",".$hive.",".$descr."\n"; + } + else { + print $count.". ".$pkg." v.".$version." [".$hive."]\n"; +# printf "%-20s %-10s %-10s\n",$pkg,$version,$hive; + print " - ".$descr."\n\n"; + $count++; + } + }; + print "Error: $@\n" if ($@); + } + exit; +} + +#------------------------------------------------------------- +# +#------------------------------------------------------------- +if ($config{file}) { +# First, check that a hive file was identified, and that the path is +# correct + my $hive = $config{reg}; + die "You must enter a hive file path/name.\n" if ($hive eq ""); + die $hive." not found.\n" unless (-e $hive); + + my %plugins = parsePluginsFile($config{file}); + if (%plugins) { + logMsg("Parsed Plugins file."); + } + else { + logMsg("Plugins file not parsed."); + exit; + } + foreach my $i (sort {$a <=> $b} keys %plugins) { + eval { + require "plugins\\".$plugins{$i}."\.pl"; + $plugins{$i}->pluginmain($hive); + }; + if ($@) { + logMsg("Error in ".$plugins{$i}.": ".$@); + } + logMsg($plugins{$i}." complete."); + rptMsg("-" x 40); + } +} + +#------------------------------------------------------------- +# +#------------------------------------------------------------- +if ($config{reg} && $config{guess}) { +# Attempt to guess which kind of hive we have + my $hive = $config{reg}; + die "You must enter a hive file path/name.\n" if ($hive eq ""); + die $hive." not found.\n" unless (-e $hive); + + my $reg; + my $root_key; + my %guess; + eval { + $reg = Parse::Win32Registry->new($hive); + $root_key = $reg->get_root_key; + }; + ::rptMsg($config{reg}." may not be a valid hive.") if ($@); + +# Check for SAM + eval { + $guess{sam} = 1 if (my $key = $root_key->get_subkey("SAM\\Domains\\Account\\Users")); + }; +# Check for Software + eval { + $guess{software} = 1 if ($root_key->get_subkey("Microsoft\\Windows\\CurrentVersion") && + $root_key->get_subkey("Microsoft\\Windows NT\\CurrentVersion")); + }; + +# Check for System + eval { + $guess{system} = 1 if ($root_key->get_subkey("MountedDevices") && + $root_key->get_subkey("Select")); + }; + +# Check for Security + eval { + $guess{security} = 1 if ($root_key->get_subkey("Policy\\Accounts") && + $root_key->get_subkey("Policy\\PolAdtEv")); + }; +# Check for NTUSER.DAT + eval { + $guess{ntuser} = 1 if ($root_key->get_subkey("Software\\Microsoft\\Windows\\CurrentVersion")); + + }; + + foreach my $g (keys %guess) { + ::rptMsg(sprintf "%-8s = %-2s",$g,$guess{$g}); + } +} + +#------------------------------------------------------------- +# +#------------------------------------------------------------- +if ($config{plugin}) { +# First, check that a hive file was identified, and that the path is +# correct + my $hive = $config{reg}; + die "You must enter a hive file path/name.\n" if ($hive eq ""); + die $hive." not found.\n" unless (-e $hive); + +# check to see if the plugin exists + my $plugin = $config{plugin}; + my $pluginfile = $plugindir.$config{plugin}."\.pl"; + die $pluginfile." not found.\n" unless (-e $pluginfile); + + eval { + require $pluginfile; + $plugin->pluginmain($hive); + }; + if ($@) { + logMsg("Error in ".$pluginfile.": ".$@); + } +} + +sub _syntax { + print<< "EOT"; +Rip v.$VERSION - CLI RegRipper tool +Rip [-r Reg hive file] [-f plugin file] [-p plugin module] [-l] [-h] +Parse Windows Registry files, using either a single module, or a plugins file. +All plugins must be located in the \"plugins\" directory; default plugins file +used if no other filename given is \"plugins\\plugins\"\. + + -r Reg hive file...Registry hive file to parse + -g ................Guess the hive file (experimental) + -f [plugin file]...use the plugin file (default: plugins\\plugins) + -p plugin module...use only this module + -l ................list all plugins + -c ................Output list in CSV format (use with -l) + -s system name.....Server name (TLN support) + -u username........User name (TLN support) + -h.................Help (print this information) + +Ex: C:\\>rr -r c:\\case\\system -f system + C:\\>rr -r c:\\case\\ntuser.dat -p userassist + C:\\>rr -l -c + +All output goes to STDOUT; use redirection (ie, > or >>) to output to a file\. + +copyright 2011 Quantum Analytics Research, LLC +EOT +} + +#------------------------------------------------------------- +# +#------------------------------------------------------------- +sub logMsg { + print STDERR $_[0]."\n"; +} + +#------------------------------------------------------------- +# +#------------------------------------------------------------- +sub rptMsg { + binmode STDOUT,":utf8"; + if ($config{sys} || $config{user}) { + my @vals = split(/\|/,$_[0],5); + my $str = $vals[0]."|".$vals[1]."|".$config{sys}."|".$config{user}."|".$vals[4]; + print $str."\n"; + } + else { + print $_[0]."\n"; + } +} + +#------------------------------------------------------------- +# parsePluginsFile() +# Parse the plugins file and get a list of plugins +#------------------------------------------------------------- +sub parsePluginsFile { + my $file = $_[0]; + my %plugins; +# Parse a file containing a list of plugins +# Future versions of this tool may allow for the analyst to +# choose different plugins files + my $pluginfile = $plugindir.$file; + if (-e $pluginfile) { + open(FH,"<",$pluginfile); + my $count = 1; + while(<FH>) { + chomp; + next if ($_ =~ m/^#/ || $_ =~ m/^\s+$/); +# next unless ($_ =~ m/\.pl$/); + next if ($_ eq ""); + $_ =~ s/^\s+//; + $_ =~ s/\s+$//; + $plugins{$count++} = $_; + } + close(FH); + return %plugins; + } + else { + return undef; + } +} + +#------------------------------------------------------------- +# getTime() +# Translate FILETIME object (2 DWORDS) to Unix time, to be passed +# to gmtime() or localtime() +#------------------------------------------------------------- +sub getTime($$) { + my $lo = shift; + my $hi = shift; + my $t; + + if ($lo == 0 && $hi == 0) { + $t = 0; + } else { + $lo -= 0xd53e8000; + $hi -= 0x019db1de; + $t = int($hi*429.4967296 + $lo/1e7); + }; + $t = 0 if ($t < 0); + return $t; +} \ No newline at end of file diff --git a/thirdparty/rr/rr.exe b/thirdparty/rr/rr.exe new file mode 100644 index 0000000000000000000000000000000000000000..0a89f5b83cb5a9c6f00f7db15e233de2cc0abc64 Binary files /dev/null and b/thirdparty/rr/rr.exe differ diff --git a/thirdparty/rr/rr.pl b/thirdparty/rr/rr.pl new file mode 100644 index 0000000000000000000000000000000000000000..397e486b4f6898f9b7b9f407270b48fc47b01113 --- /dev/null +++ b/thirdparty/rr/rr.pl @@ -0,0 +1,441 @@ +#! c:\perl\bin\perl.exe +#----------------------------------------------------------- +# Registry Ripper +# Parse a Registry hive file for data pertinent to an investigation +# +# Adv version...provides the basic functionality. All plugins +# can be used with both the basic version and the full-featured +# version +# +# Change History: +# 20081111 - Updated code in setUpEnv() to parse the file paths for +# output files (log, etc) so that they paths were handled +# properly; updated Perl2Exe include statements to support +# Parse::Win32Registry 0.40 +# 20080512 - Consolidated Basic and Advanced versions into a single +# track +# 20080429 - Fixed issue with output report and log files having the +# same (.log) file extension +# 20080422 - Added ComboBox to choose plugins file +# 20080414 - updated code to check for a selected hive file; set +# default plugin file to "ntuser" if none selected; check +# for plugins file with no plugins or all plugins commented +# out; keep track of plugins w/ hard errors generated via +# this GUI. +# 20080412 - added listbox; populate with list of plugin files +# from plugin dir +# - Log file now based on report file name and location +# 20080226 - added eval{} to wrap require pragma in go_Click() +# +# +# Functionality: +# - plugins file is selectable +# +# copyright 2008 H. Carvey, keydet89@yahoo.com +#----------------------------------------------------------- +#use strict; +use Win32::GUI(); +use Parse::Win32Registry qw(:REG_); + +# Included to permit compiling via Perl2Exe +#perl2exe_include "Parse/Win32Registry.pm"; +#perl2exe_include "Parse/Win32Registry/Key.pm"; +#perl2exe_include "Parse/Win32Registry/Entry.pm"; +#perl2exe_include "Parse/Win32Registry/Value.pm"; +#perl2exe_include "Parse/Win32Registry/File.pm"; +#perl2exe_include "Parse/Win32Registry/Win95/File.pm"; +#perl2exe_include "Parse/Win32Registry/Win95/Key.pm"; +#perl2exe_include "Encode/Unicode.pm"; +#----------------------------------------------------------- +# Global variables +#----------------------------------------------------------- +my $VERSION = "2\.02"; +my %env; + +#----------------------------------------------------------- +# GUI +#----------------------------------------------------------- +# create our menu +my $menu = Win32::GUI::MakeMenu( + "&File" => "File", + " > O&pen..." => { -name => "Open"}, + " > -" => 0, + " > E&xit" => { -name => "Exit", -onClick => sub {exit 1;}}, + "&Help" => "Help", + " > &About" => { -name => "About", -onClick => \&RR_OnAbout}, +); + +# Create Main Window +my $main = new Win32::GUI::Window ( + -name => "Main", + -title => "Registry Ripper, v.".$VERSION, + -pos => [200, 200], +# Format: [width, height] + -maxsize => [500, 420], + -size => [500, 420], + -menu => $menu, + -dialogui => 1, +) or die "Could not create a new Window: $!\n"; + +$main->AddLabel( + -text => "Hive File:", + -left => 20, + -top => 10); + +my $ntuserfile = $main->AddTextfield( + -name => "ntuserdat", + -tabstop => 1, + -left => 100, + -top => 10, + -width => 250, + -height => 22, + -tabstop => 1, + -foreground => "#000000", + -background => "#FFFFFF"); + +my $browse1 = $main->AddButton( + -name => 'browse1', + -left => 375, + -top => 10, + -width => 50, + -height => 22, + -tabstop => 1, + -text => "Browse"); + +$main->AddLabel( + -text => "Report File:", + -left => 20, + -top => 50); + +my $rptfile = $main->AddTextfield( + -name => "rptfile", + -tabstop => 1, + -left => 100, + -top => 50, + -width => 250, + -height => 22, + -tabstop => 1, + -foreground => "#000000", + -background => "#FFFFFF"); + +my $browse2 = $main->AddButton( + -name => 'browse2', + -left => 375, + -top => 50, + -width => 50, + -height => 22, + -tabstop => 1, + -text => "Browse"); + +$main->AddLabel( + -text => "Plugin File:", + -left => 20, + -top => 90); + +# http://perl-win32-gui.sourceforge.net/cgi-bin/docs.cgi?doc=combobox +my $combo = $main->AddCombobox( + -name => "Combobox", +# -dropdown => 1, + -dropdownlist => 1, + -top => 90, + -left => 100, + -width => 120, + -height => 110, + -tabstop=> 1, + ); + +my $testlabel = $main->AddLabel( + -text => "", + -name => "TestLabel", + -pos => [10,140], + -size => [445,160], + -frame => etched, + -sunken => 1 +); + +my $report = $main->AddTextfield( + -name => "Report", + -pos => [20,150], + -size => [425,140], + -multiline => 1, + -vscroll => 1, + -autohscroll => 1, + -autovscroll => 1, + -keepselection => 1 , + -tabstop => 1, +); + +my $go = $main->AddButton( + -name => 'go', + -left => 320, + -top => 310, + -width => 50, + -height => 25, + -tabstop => 1, + -text => "Rip It"); + +$main->AddButton( + -name => 'close', + -left => 390, + -top => 310, + -width => 50, + -height => 25, + -tabstop => 1, + -text => "Close"); + +my $status = new Win32::GUI::StatusBar($main, + -text => "Registry Ripper v.".$VERSION." opened.", +); + +populatePluginsList(); +$combo->Text("<Select>"); +$status->Text("Plugins List Populated."); + +$main->Show(); +Win32::GUI::Dialog(); +#----------------------------------------------------------- +sub Open_Click { + \&browse1_Click(); +} + +sub browse1_Click { + # Open a file + my $file = Win32::GUI::GetOpenFileName( + -owner => $main, + -title => "Open a hive file", + -filter => ['All files' => '*.*',], + ); + if (-e $file) { + $ntuserfile->Text($file); + + } elsif (Win32::GUI::CommDlgExtendedError()) { + $main->MessageBox ("ERROR : ".Win32::GUI::CommDlgExtendedError(), + "GetOpenFileName Error"); + } + 0; +} + +sub browse2_Click { + # Open a file + my $file = Win32::GUI::GetSaveFileName( + -owner => $main, + -title => "Save a report file", + -filter => [ + 'Report file (*.txt)' => '*.txt', + 'All files' => '*.*', + ], + ); + if ($file) { + $file = $file."\.txt" unless ($file =~ m/\.\w+$/i); + $rptfile->Text($file); + + } elsif (Win32::GUI::CommDlgExtendedError()) { + $main->MessageBox ("ERROR : ".Win32::GUI::CommDlgExtendedError(), + "GetOpenFileName Error"); + } + 0; +} + +sub go_Click { +# Set up the environment + setUpEnv(); + if ($env{ntuser} eq "") { + Win32::GUI::MessageBox($main,$ENV{USERNAME}.", you did not select a hive file.\r\n", + "Doh!!",16); + return; + } +# Get the selected item from the Plugins file listbox +# only allows for single selections at this time; defaults to ntuser +# if none selected + my $pluginfile = $combo->GetLBText($combo->GetCurSel()); + $pluginfile = "ntuser" if ($pluginfile eq ""); + $report->Append("Logging to ".$env{logfile}."\r\n"); + $report->Append("Using plugins file ".$pluginfile."\r\n"); + logMsg("Log opened."); + logMsg("File: ".$env{ntuser}); + logMsg("Environment set up."); + my %plugins = parsePluginsFile($pluginfile); + logMsg("Parsed Plugins file ".$pluginfile); + if (scalar(keys %plugins) == 0) { + Win32::GUI::MessageBox($main,$ENV{USERNAME}.", the plugins file has no plugins!!.\r\n", + "Doh!!",16); + return; + } + my $err_cnt = 0; + foreach my $i (sort {$a <=> $b} keys %plugins) { + eval { + require "plugins\\".$plugins{$i}."\.pl"; + $plugins{$i}->pluginmain($env{ntuser}); + }; + if ($@) { + $err_cnt++; + logMsg("Error in ".$plugins{$i}.": ".$@); + } + + $report->Append($plugins{$i}."...Done.\r\n"); + $status->Text($plugins{$i}." completed."); + + Win32::GUI::DoEvents(); + logMsg($err_cnt." plugins completed with errors."); + logMsg($plugins{$i}." complete."); + rptMsg("-" x 40); + } + $report->Append($err_cnt." plugins completed with errors.\r\n"); + $status->Text("Done."); +} + +sub close_Click { + exit 1; +} + +sub Combobox_CloseUp { + $status->Text("Plugin File = ".$combo->GetLBText($combo->GetCurSel())); + +} + + +# About box +sub RR_OnAbout { + my $self = shift; + + $self->MessageBox( + "Registry Ripper, v.".$VERSION."\r\n". + "Parses Registry hive (NTUSER\.DAT, System, etc.) files, placing pertinent info in a report\r\n". + "file in a readable manner.\r\n". + "Copyright 2008 H\. Carvey, keydet89\@yahoo\.com", + "About...", + MB_ICONINFORMATION | MB_OK, + ); + 0; +} +#----------------------------------------------------------- + +#----------------------------------------------------------- +sub setUpEnv { + $env{ntuser} = $ntuserfile->Text(); + $env{rptfile} = $rptfile->Text(); +# Ensure that the report file has a .txt extension if none was given + $env{rptfile} = $env{rptfile}."\.txt" unless ($env{rptfile} =~ m/\.\w+$/i); + $rptfile->Text($env{rptfile}); + + my @path = split(/\\/,$env{rptfile}); + my $last = scalar(@path) - 1; + my @f = split(/\./,$path[$last]); + my $ext = $f[scalar(@f) - 1]; + +# Assemble path to log file + $f[scalar(@f) - 1] = "log"; + $path[$last] = join('.',@f); + print join('\\',@path)."\n"; + $env{logfile} = join('\\',@path); + +# Use the above code to set up the path to the Timeline +# (.tln) file +# Assemble path to log file +# $f[scalar(@f) - 1] = "tln"; +# $path[$last] = join('.',@f); +# print join('\\',@path)."\n"; +# $env{tlnfile} = join('\\',@path); + +} + +#----------------------------------------------------------- +# get a list of plugins files from the plugins dir +#----------------------------------------------------------- +sub getPluginsFiles { + my @pluginfiles; + opendir(DIR,"plugins"); + my @files = readdir(DIR); + close(DIR); + + foreach my $f (@files) { + next if ($f =~ m/^\./); + next if ($f =~ m/\.pl$/); + push(@pluginfiles,$f); + } + return @pluginfiles; +} + +#----------------------------------------------------------- +# populate the list of plugins files +#----------------------------------------------------------- +sub populatePluginsList { + my @files = getPluginsFiles(); + foreach my $f (@files) { + $combo->InsertItem($f); + } +} + +#----------------------------------------------------------- +# +#----------------------------------------------------------- +sub parsePluginsFile { + my $file = $_[0]; + my %plugins; +# Parse a file containing a list of plugins +# Future versions of this tool may allow for the analyst to +# choose different plugins files + my $pluginfile = "plugins\\".$file; + if (-e $pluginfile) { + open(FH,"<",$pluginfile); + my $count = 1; + while(<FH>) { + chomp; + next if ($_ =~ m/^#/ || $_ =~ m/^\s+$/); +# next unless ($_ =~ m/\.pl$/); + next if ($_ eq ""); + $_ =~ s/^\s+//; + $_ =~ s/\s+$//; + $plugins{$count++} = $_; + } + close(FH); + $status->Text("Plugin file parsed and loaded."); + return %plugins; + } + else { + $report->Append($pluginfile." not found.\r\n"); + return undef; + } +} + +sub logMsg { + open(FH,">>",$env{logfile}); + print FH localtime(time).": ".$_[0]."\n"; + close(FH); +} + +sub rptMsg { + open(FH,">>",$env{rptfile}); + binmode FH,":utf8"; + print FH $_[0]."\n"; + close(FH); +} + +# sub tlnMsg { +# Need to set the format for the pipe-delimited line to be +# written in the TSK TimeMachine format +# open(FH,">>",$env{tlnfile}); +# print FH $_[0]."\n"; +# close(FH); +#} + +#------------------------------------------------------------- +# getTime() +# Translate FILETIME object (2 DWORDS) to Unix time, to be passed +# to gmtime() or localtime() +#------------------------------------------------------------- +sub getTime($$) { + my $lo = shift; + my $hi = shift; + my $t; + + if ($lo == 0 && $hi == 0) { + $t = 0; + } else { + $lo -= 0xd53e8000; + $hi -= 0x019db1de; + $t = int($hi*429.4967296 + $lo/1e7); + }; + $t = 0 if ($t < 0); + return $t; +} \ No newline at end of file diff --git a/trove/build.xml b/trove/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..c68221af25518aeab80cd3de949b7325d7966e63 --- /dev/null +++ b/trove/build.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- You may freely edit this file. See harness/README in the NetBeans platform --> +<!-- for some information on what you could do (e.g. targets to override). --> +<!-- If you delete this file and reopen the project it will be recreated. --> +<project name="org.gnu.trove" default="netbeans" basedir="."> + <description>Builds, tests, and runs the project org.gnu.trove.</description> + <import file="nbproject/build-impl.xml"/> +</project> diff --git a/trove/manifest.mf b/trove/manifest.mf new file mode 100644 index 0000000000000000000000000000000000000000..7eb568c522efa25ce9a137b2173772ca8618af9d --- /dev/null +++ b/trove/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.gnu.trove +OpenIDE-Module-Localizing-Bundle: org/gnu/trove/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + diff --git a/trove/nbproject/build-impl.xml b/trove/nbproject/build-impl.xml new file mode 100644 index 0000000000000000000000000000000000000000..c8725838c80373a22c2f7b6ccf494e9c86f06020 --- /dev/null +++ b/trove/nbproject/build-impl.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +*** GENERATED FROM project.xml - DO NOT EDIT *** +*** EDIT ../build.xml INSTEAD *** +--> +<project name="org.gnu.trove-impl" basedir=".."> + <fail message="Please build using Ant 1.7.1 or higher."> + <condition> + <not> + <antversion atleast="1.7.1"/> + </not> + </condition> + </fail> + <property file="nbproject/private/suite-private.properties"/> + <property file="nbproject/suite.properties"/> + <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail> + <property file="${suite.dir}/nbproject/private/platform-private.properties"/> + <property file="${suite.dir}/nbproject/platform.properties"/> + <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2"> + <attribute name="name"/> + <attribute name="value"/> + <sequential> + <property name="@{name}" value="${@{value}}"/> + </sequential> + </macrodef> + <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2"> + <attribute name="property"/> + <attribute name="value"/> + <sequential> + <property name="@{property}" value="@{value}"/> + </sequential> + </macrodef> + <property file="${user.properties.file}"/> + <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> + <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> + <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> + <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness)."> + <condition> + <not> + <contains string="${cluster.path.evaluated}" substring="platform"/> + </not> + </condition> + </fail> + <import file="${harness.dir}/build.xml"/> +</project> diff --git a/trove/nbproject/genfiles.properties b/trove/nbproject/genfiles.properties new file mode 100644 index 0000000000000000000000000000000000000000..b15062e889cbd0460be9a5cd42b60d5a147d7680 --- /dev/null +++ b/trove/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=f46defa5 +build.xml.script.CRC32=9f9a492d +build.xml.stylesheet.CRC32=a56c6a5b@1.46.1 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=f46defa5 +nbproject/build-impl.xml.script.CRC32=62e537b6 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.46.1 diff --git a/trove/nbproject/platform.properties b/trove/nbproject/platform.properties new file mode 100644 index 0000000000000000000000000000000000000000..38ecd5a92ebea2c14710d0595bdd2d6df0bafcf4 --- /dev/null +++ b/trove/nbproject/platform.properties @@ -0,0 +1,99 @@ +cluster.path=\ + ${nbplatform.active.dir}/java:\ + ${nbplatform.active.dir}/platform +disabled.modules=\ + org.apache.tools.ant.module,\ + org.netbeans.api.debugger.jpda,\ + org.netbeans.api.java,\ + org.netbeans.libs.cglib,\ + org.netbeans.libs.javacapi,\ + org.netbeans.libs.javacimpl,\ + org.netbeans.libs.jsr223,\ + org.netbeans.libs.springframework,\ + org.netbeans.modules.ant.browsetask,\ + org.netbeans.modules.ant.debugger,\ + org.netbeans.modules.ant.freeform,\ + org.netbeans.modules.ant.grammar,\ + org.netbeans.modules.ant.kit,\ + org.netbeans.modules.beans,\ + org.netbeans.modules.classfile,\ + org.netbeans.modules.dbschema,\ + org.netbeans.modules.debugger.jpda,\ + org.netbeans.modules.debugger.jpda.ant,\ + org.netbeans.modules.debugger.jpda.projects,\ + org.netbeans.modules.debugger.jpda.ui,\ + org.netbeans.modules.form,\ + org.netbeans.modules.form.j2ee,\ + org.netbeans.modules.form.kit,\ + org.netbeans.modules.hibernate,\ + org.netbeans.modules.hibernatelib,\ + org.netbeans.modules.hudson.ant,\ + org.netbeans.modules.hudson.maven,\ + org.netbeans.modules.i18n,\ + org.netbeans.modules.i18n.form,\ + org.netbeans.modules.j2ee.core.utilities,\ + org.netbeans.modules.j2ee.eclipselink,\ + org.netbeans.modules.j2ee.eclipselinkmodelgen,\ + org.netbeans.modules.j2ee.jpa.refactoring,\ + org.netbeans.modules.j2ee.jpa.verification,\ + org.netbeans.modules.j2ee.metadata,\ + org.netbeans.modules.j2ee.metadata.model.support,\ + org.netbeans.modules.j2ee.persistence,\ + org.netbeans.modules.j2ee.persistence.kit,\ + org.netbeans.modules.j2ee.persistenceapi,\ + org.netbeans.modules.j2ee.toplinklib,\ + org.netbeans.modules.java.api.common,\ + org.netbeans.modules.java.debug,\ + org.netbeans.modules.java.editor,\ + org.netbeans.modules.java.editor.lib,\ + org.netbeans.modules.java.examples,\ + org.netbeans.modules.java.freeform,\ + org.netbeans.modules.java.guards,\ + org.netbeans.modules.java.helpset,\ + org.netbeans.modules.java.hints,\ + org.netbeans.modules.java.hints.processor,\ + org.netbeans.modules.java.j2seplatform,\ + org.netbeans.modules.java.j2seproject,\ + org.netbeans.modules.java.kit,\ + org.netbeans.modules.java.lexer,\ + org.netbeans.modules.java.navigation,\ + org.netbeans.modules.java.platform,\ + org.netbeans.modules.java.preprocessorbridge,\ + org.netbeans.modules.java.project,\ + org.netbeans.modules.java.source,\ + org.netbeans.modules.java.source.ant,\ + org.netbeans.modules.java.sourceui,\ + org.netbeans.modules.javadoc,\ + org.netbeans.modules.javawebstart,\ + org.netbeans.modules.jellytools,\ + org.netbeans.modules.jellytools.java,\ + org.netbeans.modules.junit,\ + org.netbeans.modules.maven,\ + org.netbeans.modules.maven.coverage,\ + org.netbeans.modules.maven.embedder,\ + org.netbeans.modules.maven.grammar,\ + org.netbeans.modules.maven.graph,\ + org.netbeans.modules.maven.hints,\ + org.netbeans.modules.maven.indexer,\ + org.netbeans.modules.maven.junit,\ + org.netbeans.modules.maven.kit,\ + org.netbeans.modules.maven.model,\ + org.netbeans.modules.maven.osgi,\ + org.netbeans.modules.maven.persistence,\ + org.netbeans.modules.maven.repository,\ + org.netbeans.modules.maven.search,\ + org.netbeans.modules.maven.spring,\ + org.netbeans.modules.projectimport.eclipse.core,\ + org.netbeans.modules.projectimport.eclipse.j2se,\ + org.netbeans.modules.refactoring.java,\ + org.netbeans.modules.spellchecker.bindings.java,\ + org.netbeans.modules.spring.beans,\ + org.netbeans.modules.swingapp,\ + org.netbeans.modules.websvc.jaxws21,\ + org.netbeans.modules.websvc.jaxws21api,\ + org.netbeans.modules.websvc.saas.codegen.java,\ + org.netbeans.modules.xml.jaxb,\ + org.netbeans.modules.xml.tools.java,\ + org.openide.compat,\ + org.openide.util.enumerations +nbplatform.active=default diff --git a/trove/nbproject/project.properties b/trove/nbproject/project.properties new file mode 100644 index 0000000000000000000000000000000000000000..c4a287af7f9698f4a4fe857e05578adf9aefacbf --- /dev/null +++ b/trove/nbproject/project.properties @@ -0,0 +1 @@ +is.autoload=true diff --git a/trove/nbproject/project.xml b/trove/nbproject/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..4813201efdd2f5c1b73ebf95a8a784e21b2331c2 --- /dev/null +++ b/trove/nbproject/project.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://www.netbeans.org/ns/project/1"> + <type>org.netbeans.modules.apisupport.project</type> + <configuration> + <data xmlns="http://www.netbeans.org/ns/nb-module-project/3"> + <code-name-base>org.gnu.trove</code-name-base> + <suite-component/> + <module-dependencies/> + <public-packages> + <package>gnu.trove</package> + <package>gnu.trove.decorator</package> + <package>gnu.trove.function</package> + <package>gnu.trove.impl</package> + <package>gnu.trove.impl.hash</package> + <package>gnu.trove.impl.sync</package> + <package>gnu.trove.impl.unmodifiable</package> + <package>gnu.trove.iterator</package> + <package>gnu.trove.iterator.hash</package> + <package>gnu.trove.list</package> + <package>gnu.trove.list.array</package> + <package>gnu.trove.list.linked</package> + <package>gnu.trove.map</package> + <package>gnu.trove.map.custom_hash</package> + <package>gnu.trove.map.hash</package> + <package>gnu.trove.procedure</package> + <package>gnu.trove.procedure.array</package> + <package>gnu.trove.queue</package> + <package>gnu.trove.set</package> + <package>gnu.trove.set.hash</package> + <package>gnu.trove.stack</package> + <package>gnu.trove.stack.array</package> + <package>gnu.trove.strategy</package> + </public-packages> + <class-path-extension> + <runtime-relative-path>ext/trove-3.0.2.jar</runtime-relative-path> + <binary-origin>release/modules/ext/trove-3.0.2.jar</binary-origin> + </class-path-extension> + </data> + </configuration> +</project> diff --git a/trove/nbproject/suite.properties b/trove/nbproject/suite.properties new file mode 100644 index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92 --- /dev/null +++ b/trove/nbproject/suite.properties @@ -0,0 +1 @@ +suite.dir=${basedir}/.. diff --git a/trove/release/modules/ext/trove-3.0.2.jar b/trove/release/modules/ext/trove-3.0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..12fb57681f8ca343350c8f43f1a8c007045936ec Binary files /dev/null and b/trove/release/modules/ext/trove-3.0.2.jar differ diff --git a/trove/src/org/gnu/trove/Bundle.properties b/trove/src/org/gnu/trove/Bundle.properties new file mode 100644 index 0000000000000000000000000000000000000000..c6178bf414c9ddddd3a94dd39851bc5d76b01f68 --- /dev/null +++ b/trove/src/org/gnu/trove/Bundle.properties @@ -0,0 +1 @@ +OpenIDE-Module-Name=trove