package info.benjaminhill.survey;
import info.benjaminhill.utils.AbstractFileScan;
import info.benjaminhill.utils.BinaryTools;
import info.benjaminhill.utils.BufferedRemote;
import info.benjaminhill.utils.ExecWrapper;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Properties;
import java.util.Queue;
/**
* @author Benjamin Hill
*
*/
public class HashApplications extends AbstractFileScan {
private static final FileFilter appFilter = new FileFilter() {
public boolean accept(final File f) {
if (f.isDirectory()) return false;
String element = null;
for (final String element2 : CACHES) {
element = element2;
if (f.getAbsolutePath().toLowerCase(Locale.US).contains(element)) return false;
}
for (final String element2 : PROGRAMS) {
element = element2;
if (f.toString().toLowerCase(Locale.US).endsWith(element)) return true;
}
return false;
}
};
private static final String[] CACHES = { "documents and settings", "local settings\\history",
"temporary internet files", ".default\\cache", "recycled", "local settings\\temp", "\\tmp\\",
"system volume information", "$hf_mig$", "windows\\installer", "pagefile", "hiberfil", "NtUninstall" };
private static final String[] PROGRAMS = { ".ade", ".adp", ".bas", ".bat", ".chm", ".cmd", ".com", ".cpl", ".crt",
".dll", ".exe", ".hlp", ".hta", ".inf", ".ini", ".ins", ".isp", ".jar", ".js", ".jse", ".lnk", ".mdb",
".mde", ".msc", ".msi", ".msp", ".mst", ".ocx", ".pcd", ".pif", ".reg", ".scr", ".shs", ".sys", ".url",
".vb", ".vbe", ".vbs", ".wsc", ".wsf", ".wsh" };
private static final String UPLOAD_URL = "http://scan.benjaminhill.info/upload.php"; // "http://localhost/scan/upload.php";
private BufferedRemote br = null;
private final Queue<File> dirQueue = new LinkedList<File>();
private StatusInterface gui = null;
@Override
public void handleDirectory(final File dir) {
this.dirQueue.add(dir);
}
@Override
public void handleFile(final File f) {
// empty
}
@Override
public void run() {
this.gui.sendMessage("This survey is read-only, the contents of your hard drive are not altered in any way.\n"
+ " Only 'executable' files are surveyed, and the signature (hash) of the file are sent to us.\n"
+ " Also included is the list of loaded DLLs.\n"
+ " The actual contents of your files are NOT shared, and all submissions are anonymous!\n\n"
+ "Click OK to start... \n" + "(This will take a while, but will run nicely in the background)");
this.gui.setStatus("Starting");
this.gui.setStatus("Finding Programs...");
final File[] roots = File.listRoots();
for (final File element : roots) {
recurse(element);
}
// recurse(new File("C:\\Program Files\\Adobe"));
try {
final Properties global = new Properties();
global.setProperty("id", ExecWrapper.uniqueId());
System.out.println("ID:" + global.getProperty("id"));
this.br = new BufferedRemote(new URL(UPLOAD_URL), global);
this.gui.setMax(this.dirQueue.size());
this.gui.setStatus("Hashing program files");
int processedDirCount = 0;
Properties p;
while (!this.dirQueue.isEmpty()) {
try {
final File dir = this.dirQueue.remove();
final File[] files = dir.listFiles(appFilter);
if (files != null) {
for (final File f : files) {
p = BinaryTools.getMeta(f);
p.setProperty("path", f.getAbsolutePath().replaceAll(
"Documents and Settings\\\\([^\\\\]+)", "Documents and Settings\\\\USER\\\\")
.replace("\\\\", "\\"));
this.br.call("fingerprint", p);
}
}
} catch (Exception e) {
System.err.println(e);
}
// System.out.println("Post results:" + this.br.post());
processedDirCount++;
this.gui.setValue(processedDirCount);
}
// systemProperties();
System.out.println("Posting Results:" + this.br.post());
this.gui.setStatus("Finished, thank you! Your Completion Code: '" + ExecWrapper.uniqueId().substring(0, 5)
+ "' (" + processedDirCount + ")");
} catch (final IOException ioe) {
this.gui.setStatus("Stopping because of:" + ioe.toString());
}
}
/**
* @param progress
* the progress to set
*/
public void setGUI(final StatusInterface g) {
this.gui = g;
}
private void systemProperties() {
try {
final Properties p = new Properties();
int propCount = 0;
String element = null;
// dll
String[] execResults = ExecWrapper.exec("tasklist /FO CSV /M").split("\n");
for (final String execResult : execResults) {
element = execResult;
propCount++;
p.setProperty("d_" + propCount, element);
}
// services
execResults = ExecWrapper.exec("tasklist /FO CSV /SVC").split("\n");
for (final String execResult : execResults) {
element = execResult;
propCount++;
p.setProperty("s_" + propCount, element);
}
// verbose
execResults = ExecWrapper.exec("tasklist /FO CSV /V").split("\n");
for (final String execResult : execResults) {
element = execResult;
propCount++;
p.setProperty("v_" + propCount, element);
}
// Useful, but not anonymous enough
// this.pzos.println("[netstat]");
// this.pzos.println(ExecWrapper.exec("netstat -ano"));
// env - don't want everything, too much non-anonymous info
final String[] envs = new String[] { "TEMP", "SystemDrive", "ProgramFiles", "HOMEDRIVE",
"PROCESSOR_REVISION", "PROCESSOR_IDENTIFIER", "TMP", "PROCESSOR_ARCHITECTURE", "OS",
"PROCESSOR_LEVEL", "windir", "SystemRoot" };
for (final String env : envs) {
element = env;
p.setProperty("e_" + element, System.getenv(element));
} // prop - may need to cut other things to keep anonymous
final Iterator<Object> keys = System.getProperties().keySet().iterator();
while (keys.hasNext()) {
final String k2 = (String) keys.next();
if (k2.startsWith("java.") || k2.startsWith("os.") || k2.startsWith("sun."))
if (System.getProperty(k2).indexOf("Documents and Settings") < 1)
p.setProperty("p_" + k2, System.getProperty(k2));
}
this.br.call("system", p);
} catch (final RuntimeException ioe) {
System.err.println("Problem with system properties:" + ioe.toString());
}
}
}