Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- EnCase Endpoint Investigator EnScript example.
- Tested on EnCase 20.4.0.120.
- Report bugs to:
- Simon Key <skey@opentext.com>
- 1st December 2020
- */
- class MainClass {
- SafeClass Safe; // Object to connect to SAFE
- RoleClass RoleRoot, // List of all roles for a given user
- Role; // Role user choose to take
- NetworkClass SweepNet; // List of remote nodes to connect to
- String NetText, // Textual list of remote nodes
- ClientReturnAddress, // For NODECLIENT connection options
- StatusBarName, // Name to be displayed in the status bar
- SuccessfulLabel, // Snapshot and bookmark label for successful connections
- FailedLabel; // Snapshot and bookmark label for failed connections
- int NumConnections, // Number of SAFE connections to use
- ConnectOptions; // Connection Options: INDIRECT, CLIENTNODELOCAL, CLIENTNODESAFE, NODECLIENT
- BookmarkClass RootBMFolder, // Top-level bookmark folder for script output
- SuccessfulConnectionsBMFolder, // Bookmark folder for successful connections
- FailedConnectionsBMFolder; // Bookmark folder for failed connections
- SnapshotClass SuccessfulSnapshots, // Snapshot container for successful connections
- FailedSnapshots; // Snapshot container for failed connections
- MainClass() :
- Safe(),
- RoleRoot(),
- Role(),
- SweepNet(),
- NumConnections = 20, //can be changed depending on workload
- ConnectOptions = ConnectionClass::CLIENTNODESAFE,
- StatusBarName = "Encase Agent Connectivity Test", //can be changed depending on organizational input
- SuccessfulLabel = "Successful Connections",
- FailedLabel = "Failed Connections",
- SuccessfulSnapshots(null, SuccessfulLabel),
- FailedSnapshots(null, FailedLabel)
- {
- }
- /**
- Entry point of the Enscript
- **/
- void Main(CaseClass c)
- {
- if (c)
- {
- SystemClass::ClearConsole();
- if (Safe.Logon(null) && ShowDiag() == SystemClass::OK)
- {
- RootBMFolder = new BookmarkClass(c.BookmarkRoot(), String::Format("{0} Results", StatusBarName), NodeClass::FOLDER);
- SuccessfulConnectionsBMFolder = new BookmarkClass(RootBMFolder, SuccessfulLabel, NodeClass::FOLDER),
- FailedConnectionsBMFolder = new BookmarkClass(RootBMFolder, FailedLabel, NodeClass::FOLDER),
- Sweep();
- BookmarkSnapshots(SuccessfulConnectionsBMFolder, SuccessfulSnapshots, SuccessfulLabel);
- BookmarkSnapshots(FailedConnectionsBMFolder, FailedSnapshots, FailedLabel);
- SystemClass::Message(ICONINFORMATION, "Success", String::Format("{0}: Completed successfully!", StatusBarName));
- }
- }
- else
- {
- SystemClass::Message(ICONSTOP, "Error", "Need an open case so that the results can be bookmarked!");
- }
- }
- /**
- Bookmark the resultant snapshots
- **/
- void BookmarkSnapshots(BookmarkClass folder, SnapshotClass snap, const String &name)
- {
- BookmarkDataClass data(folder, name);
- data.SetRoot(snap);
- }
- /**
- This method contains the logic we want to apply to each node on the network
- **/
- void Process(ConnectionClass conn, SnapshotClass ss, const String &name)
- {
- Console.WriteLine("Attempting to determine PATH environment variable for {0} ({1}).", name, ss.IPAddress());
- String path_environment_variable;
- String comment;
- if (conn.ResolveVariable("PATH", path_environment_variable))
- {
- comment = String::Format("PATH environment variable on {0}:\n\n{1}\n", name, path_environment_variable);
- }
- else
- {
- comment = String::Format("Can't resolve PATH environment variable on {0}.", name);
- }
- Console.WriteLine(comment);
- BookmarkClass sub(SuccessfulConnectionsBMFolder, name, NodeClass::FOLDER),
- note(sub, String::Format("PATH Environment Variable on {0}", name));
- sub.SetComment(String::Format("Processing results for {0}.", name));
- note.SetComment(comment);
- }
- /**
- Display dialogs
- **/
- int ShowDiag()
- {
- RoleRoot = Safe.RoleRoot();
- DialogClass diag();
- new NetTextDialogClass(diag, this);
- return diag.Wizard();
- }
- /**
- Create a note-bookmark for a connection , failed or otherwise
- **/
- void BookmarkConnection(BookmarkClass folder, const String &name, const String &comment)
- {
- BookmarkClass note(folder, name);
- note.SetComment(comment);
- }
- /**
- Code to remove trailing newline characters from certain SAFE
- error messages.
- **/
- String RemoveTrailingNewLine(const String &value)
- {
- String retval = value;
- retval.Trim("\n", TRIMEND);
- return retval;
- }
- /**
- Code that gets connection and snapshot
- **/
- void ReadNetwork(BatchClass batch)
- {
- String message,
- name,
- comment;
- do
- {
- ConnectionClass conn;
- SnapshotClass ss();
- message = "";
- BatchClass::ConnectionTypes reply = batch.GetConnection(conn, ss, name, message, 0);
- if (reply == BatchClass::BATCHCONNECT) //successfully connected to remote node
- {
- comment = String::Format("Got connection to {0}.", name);
- Console.WriteLine(comment);
- SuccessfulSnapshots.Insert(ss);
- Process(conn, ss, name);
- SystemClass::StatusInc(1);
- }
- else if (reply == BatchClass::BATCHERROR) //could not connect to remote node. ss object will have the state of the node
- {
- comment = String::Format("Could not connect to {0}. SAFE error message: {1}.", name, RemoveTrailingNewLine(message));
- Console.WriteLine(comment);
- FailedSnapshots.Insert(ss);
- BookmarkConnection(FailedConnectionsBMFolder, name, comment);
- SystemClass::StatusInc(1);
- }
- else if (reply == BatchClass::BATCHWAIT)
- {
- SystemClass::Sleep(100);
- }
- else if (reply == BatchClass::BATCHFATAL)
- {
- String err = SystemClass::LastError();
- Console.WriteLine("The SAFE is not responding: {0}. This EnScript will terminate.", RemoveTrailingNewLine(err));
- return;
- }
- } while (reply != BatchClass::BATCHDONE);
- }
- /**
- Code that creates a batchclass
- **/
- void Sweep()
- {
- DateClass now;
- BatchClass batch(Safe, Role, NumConnections, ConnectionClass::SNAPALL);
- if (batch.Add(SweepNet)) {
- batch.SetMode(ConnectionClass::Options::Convert(ConnectOptions), ClientReturnAddress);
- if (batch.Start()) {
- uint machines = batch.TotalMachines();
- Console.WriteLine("Scanning {0} using {1}.", Plural("node", machines), Plural("connection", batch.ConnectionsUsed()));
- SystemClass::StatusRange(StatusBarName, machines);
- uint start;
- now.Now();
- start = now.GetUnix();
- ReadNetwork(batch);
- now.Now();
- Console.WriteLine("Scan completed in {0} seconds.", (now.GetUnix() - start));
- }
- else {
- SystemClass::Message(ICONSTOP, "BatchClass error.", SystemClass::LastError());
- }
- }
- else {
- SystemClass::Message(ICONSTOP, "BatchClass Error", "Unable to add any IPs to the sweep.");
- }
- }
- String Plural(const String &str, uint n)
- {
- return String::Format("{0} {1}{2}", n, str, n == 1 ? "" : "s");
- }
- /**
- Turn a string of text into networkclass objects
- **/
- bool ParseText(String t)
- {
- SweepNet.Close();
- bool ret = false;
- while (t)
- {
- ret = true;
- int end = t.Find("\n");
- String line = end < 0 ? t : t.SubString(0, end);
- int dash = line.Find("-");
- if (dash > 0) {
- IPClass ip1(ExtractIP(line.SubString(0, dash))),
- ip2(ExtractIP(line.SubString(dash+1, -1)));
- if (ip1 && ip2) {
- NetworkClass n(SweepNet, "IP Range", NodeClass::SELECTED);
- n.SetStart(ip1);
- n.SetStop(ip2);
- }
- else
- NetworkClass n(SweepNet, line, NodeClass::SELECTED);
- }
- else if (line != "") {
- NetworkClass n(SweepNet, line, NodeClass::SELECTED);
- }
- if (end > 0)
- t.Delete(0, end+1);
- else
- break;
- }
- return ret;
- }
- /**
- Check for IPs in nettext
- **/
- String ExtractIP(const String &s)
- {
- String ret = s;
- ret.Trim(" ", String::TRIMSTART | String::TRIMEND);
- return ret.IsValidIPAddress() ? ret : "";
- }
- }
- /**
- Dialog to choose a role and enter nodes to sweep
- **/
- class NetTextDialogClass: DialogClass
- {
- MainClass Data;
- StaticTextClass SafeTextEdit;
- TreeEditClass Tree;
- StaticTextClass Help;
- StringEditClass NetTextEdit;
- NetTextDialogClass(DialogClass diag, MainClass d) :
- DialogClass(diag, d.StatusBarName + " Options"),
- Data = d,
- SafeTextEdit(this, "", START, 15, 200, 100, 0),
- Tree(this, "Choose The Role You Want To Assume", NEXT, START, 200, 100, 0, d.RoleRoot, 0),
- Help(this, "Enter IP addresses or machine names on separate\n"
- "lines. Enter ranges on separate lines and delimit\n"
- "the start and stop address with a dash (\"-\").\n\n"
- "Example:\n\n"
- "\tlocalhost\n"
- "\t192.168.5.5\n"
- "\t192.168.0.16-192.168.0.64\n"
- "\t192.168.1.1-192.168.3.255\n"
- "\tfd00:0:1000:20:0:0:0:100\n",
- START, NEXT, 200, 100, REQUIRED),
- NetTextEdit(this, "", NEXT, SAME, 200, 100, AUTOVSCROLL | MULTILINE | WANTRETURN, d.NetText, 9999, 0)
- {
- }
- virtual void Setup()
- {
- DialogClass::Setup();
- SafeTextEdit.SetText("SAFE:\t\t\t\t" + Data.Safe.Name() +
- "\nUser:\t\t\t\t" + Data.Safe.UserName() +
- "\n\nTotal Connections:\t\t" + Data.Safe.TotalConnections() +
- "\nActive Connections:\t\t" + Data.Safe.ActiveConnections() +
- "\nConnections To Use:\t\t" + Data.NumConnections +
- "\n\nRemediation Allowed:\t\t" + (Data.Safe.RemediationAllowed() ? "Yes" : "No") +
- "\nSnapshot Allowed:\t\t" + (Data.Safe.SnapshotAllowed() ? "Yes" : "No") +
- "\n\nSAFE Version:\t\t\t" + Data.Safe.Version()
- );
- }
- virtual void CheckControls()
- {
- DialogClass::CheckControls();
- EnableClose(Tree.GetValue().Parent());
- }
- virtual bool CanClose()
- {
- Output();
- bool ret = false;
- if (DialogClass::CanClose()) {
- Data.Role = RoleClass::TypeCast(Tree.GetValue());
- ret = Data.ParseText(Data.NetText);
- if (!ret)
- ErrorMessage("Please Enter a value in the IP List Text Area.");
- }
- return ret;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement