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.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
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$", "pagefile", "hiberfil" };
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";
// private static final String UPLOAD_URL =
// "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. All documents, mp3s, movies etc are ignored.\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("Looking for Programs...");
final File[] roots = File.listRoots();
for (final File element : roots) {
recurse(element);
}
// recurse(new File("C:\\Program Files\\Adobe"));
try {
final Map<String, String> global = new HashMap<String, String>();
global.put("id", ExecWrapper.uniqueId());
System.out.println("ID:" + global.get("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;
Map<String, String> 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.put("path", f.getAbsolutePath().replaceAll(
"Documents and Settings\\\\([^\\\\]+)",
"Documents and Settings\\\\USER\\\\")
.replace("\\\\", "\\"));
this.br.call("fingerprint", p);
}
}
} catch (final Exception e) {
System.err.println(e);
}
processedDirCount++;
this.gui.setValue(processedDirCount);
}
// systemProperties();
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 Map<String, String> p = new HashMap<String, String>();
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.put("d_" + propCount, element);
}
// services
execResults = ExecWrapper.exec("tasklist /FO CSV /SVC").split("\n");
for (final String execResult : execResults) {
element = execResult;
propCount++;
p.put("s_" + propCount, element);
}
// verbose
execResults = ExecWrapper.exec("tasklist /FO CSV /V").split("\n");
for (final String execResult : execResults) {
element = execResult;
propCount++;
p.put("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.put("e_" + element, System.getenv(element));
}
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.put("p_" + k2, System.getProperty(k2));
}
}
}
this.br.call("system", p);
} catch (final RuntimeException ioe) {
System.err.println("Problem with system properties:"
+ ioe.toString());
}
}
}