Skip to content

Commit

Permalink
Merge timtaylor3/regrippy: add usersids.py, lastshutdown.py, systemin…
Browse files Browse the repository at this point in the history
…fo.py (#2)

* Create lastshutdown.py

* Create systeminfo

* Create usersids.py

* Rename systeminfo to systeminfo.py

* Minor fixes.

* Minor Changes

* Minor Changes

* Update systeminfo.py

* Minor Changes

* Initial Commit

* Minor Changes

* Initial Commit

* Initial Commit

* Initial Commit

* Work in progress

* Initial Commit

* Initial Commit

* Logic update to check for empty IP Address.

* Removed error checking if key wasn't found.

* Removed "interface1.add_child('DhcpIPAddress')" because ti wasn't necessary.

* Fixed an issue when reading "IP Address" from a list.

* Updated test assertions.

* Fixed Key Not found logic.

* Delete network.py

Removed because it was a WIP.
  • Loading branch information
timtaylor3 authored and simsor committed Apr 24, 2019
1 parent 73c5e42 commit 48bdb13
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 0 deletions.
33 changes: 33 additions & 0 deletions regrippy/plugins/lastshutdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Plugin written by Tim Taylor, [email protected]
import struct
from Registry.RegistryParse import parse_windows_timestamp
from regrippy import BasePlugin, PluginResult, mactime


class Plugin(BasePlugin):
"""Return the last shutdown time"""
__REGHIVE__ = "SYSTEM"

def run(self):

key = self.open_key(self.get_currentcontrolset_path() + r"\Control\Windows")
if not key:
return

for v in key.values():
if v.name() == "ShutdownTime":
binary = struct.unpack('<Q', v.value())[0]
dt = parse_windows_timestamp(binary)
value = dt.isoformat('T') + 'Z'
res = PluginResult(key=key, value=v)
res.custom['LastShutdownTime'] = value
yield res

def display_human(self, result):
print("Last Shutdown Time was: {0}".format(result.custom["LastShutdownTime"]))

def display_machine(self, result):
print(mactime(name=f"{result.value_name} {result.custom['LastShutdownTime']}", mtime=result.mtime))



95 changes: 95 additions & 0 deletions regrippy/plugins/systeminfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Plugin written by Tim Taylor, [email protected]
import struct
from datetime import datetime
from Registry.RegistryParse import parse_windows_timestamp
from regrippy import BasePlugin, PluginResult, mactime


class Plugin(BasePlugin):
"""Return System Information"""
__REGHIVE__ = ["SYSTEM", "SOFTWARE"]

def run(self):
if self.hive_name == "SYSTEM":

reg_host_name = self.get_currentcontrolset_path() + r"\Control\ComputerName\ComputerName"
reg_last_shutdown = self.get_currentcontrolset_path() + r"\Control\Windows"
reg_interfaces = self.get_currentcontrolset_path() + r"\Services\Tcpip\Parameters\Interfaces"

paths = [reg_host_name, reg_last_shutdown, reg_interfaces]

else: # SOFTWARE
paths = [r"Microsoft\Windows NT\CurrentVersion"]

for path in paths:
key = self.open_key(path)

if not key:
continue

for v in key.values():
if v.name() == "ComputerName":
res = PluginResult(key=key, value=v)
hostname = v.value()
res.custom['value'] = "Hostname:\t\t{0}".format(hostname)
yield res

if v.name() == "ShutdownTime":
binary = struct.unpack('<Q', v.value())[0]
dt = parse_windows_timestamp(binary)
last_shutdown = dt.isoformat('T') + 'Z'
res = PluginResult(key=key, value=v)
res.custom['value'] = "Last Shutdown Time:\t{0}".format(last_shutdown)
yield res

if v.name() == "InstallDate":
res = PluginResult(key=key, value=v)
install_date = datetime.utcfromtimestamp(v.value()).isoformat('T') + 'Z'
res.custom['value'] = "Install Date:\t\t{0}".format(install_date)
yield res

if v.name() == "RegisteredOwner":
res = PluginResult(key=key, value=v)
registered_owner = v.value()
res.custom['value'] = "Registered Owner:\t{0}".format(registered_owner)
yield res

if v.name() == "ProductName":
res = PluginResult(key=key, value=v)
product_name = v.value()
res.custom['value'] = "Operating System:\t{0}".format(product_name)
yield res

if path.endswith('Interfaces'):
guid_list = list()
for v in key.subkeys():
guid_list.append(v.name())

for guid in guid_list:
guid_path = path + '\\' + guid
key2 = self.open_key(guid_path)

if not key2:
continue

for entry in key2.values():
if entry.name() == "IPAddress":
res = PluginResult(key=key, value=entry)
ip_address = entry.value()
if ip_address != '':
res.custom['value'] = "IP Address:\t\t{0}".format(ip_address)
yield res

if entry.name() == "DhcpIPAddress":
res = PluginResult(key=key, value=entry)
ip_address = entry.value()
res.custom['value'] = "IP Address:\t\t{0}".format(ip_address)
if ip_address != '':
res.custom['value'] = "IP Address:\t\t{0}".format(ip_address)
yield res

def display_human(self, result):
print("{0}".format(result.custom["value"]))

def display_machine(self, result):
print(mactime(name=f"{result.custom['value']}", mtime=result.mtime))
39 changes: 39 additions & 0 deletions regrippy/plugins/usersids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Plugin written by Tim Taylor, [email protected]
from regrippy import BasePlugin, PluginResult, mactime


class Plugin(BasePlugin):
"""Returns the user names with sids"""

__REGHIVE__ = "SOFTWARE"

def run(self):
path = r"Microsoft\Windows NT\CurrentVersion\ProfileList"
key = self.open_key(path)
if not key:
return

sid_list = list()

for v in key.subkeys():
sid_list.append(v.name())

for sid in sid_list:
sid_path = path + '\\' + sid
key2 = self.open_key(sid_path)

if not key2:
continue

for entry in key2.values():
if entry.name() == "ProfileImagePath":
res = PluginResult(key=key, value=entry)
user_name = entry.value().split('\\')[-1]
res.custom['value'] = '{}:\t{}'.format(user_name, key2.name())
yield res

def display_human(self, result):
print(result.custom['value'])

def display_machine(self, result):
print(mactime(name=result.custom['value'], mtime=result.mtime))
26 changes: 26 additions & 0 deletions tests/test_lastshutdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from .reg_mock import RegistryMock, RegistryKeyMock, RegistryValueMock, LoggerMock
from Registry.Registry import RegBin
import pytest

from regrippy.plugins.lastshutdown import Plugin as plugin

@pytest.fixture
def mock_reg():
key = RegistryKeyMock.build("ControlSet001\\Control\\Windows")
reg = RegistryMock("SYSTEM", "system", key.root())
reg.set_ccs(1)

val = RegistryValueMock("ShutdownTime", b'\xe40\xa5!\xed\xf7\xd3\x01', RegBin)
key.add_value(val)

return reg


def test_lastshutdown(mock_reg):
p = plugin(mock_reg, LoggerMock(), "SYSTEM", "-")

results = list(p.run())
assert(len(results) == 1), "There should be a single result"
assert(results[0].custom["LastShutdownTime"] == "2018-05-30T08:06:36.766026Z"), "It should have returned 2018-05-30T08:06:36.766026Z"


98 changes: 98 additions & 0 deletions tests/test_systeminfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from .reg_mock import RegistryMock, RegistryKeyMock, RegistryValueMock, LoggerMock
from Registry.Registry import RegSZ, RegBin
import pytest

from regrippy.plugins.systeminfo import Plugin as plugin


@pytest.fixture
def mock_software():
key = RegistryKeyMock.build("Microsoft\\Windows NT\\CurrentVersion")
reg = RegistryMock("SOFTWARE", "software", key.root())

key_install_date = RegistryKeyMock("InstallDate", key)
key_owner = RegistryKeyMock("RegisteredOwner", key)
key_product_name = RegistryKeyMock("ProductName", key)

val1 = RegistryValueMock("InstallDate", 1523364100, RegBin)
val2 = RegistryValueMock("RegisteredOwner", "Some Dude", RegSZ)
val3 = RegistryValueMock("ProductName", "Windows 7 Professional", RegSZ)

key.add_child(key_install_date)
key.add_child(key_owner)
key.add_child(key_product_name)

key.add_value(val1)
key.add_value(val2)
key.add_value(val3)

return reg


@pytest.fixture
def mock_control():
host_name = RegistryKeyMock.build("ControlSet001\\Control\\ComputerName\\ComputerName")
reg = RegistryMock("SYSTEM", "system", host_name.root())
reg.set_ccs(1)

val1 = RegistryValueMock("ComputerName", "TestPC", RegSZ)
host_name.add_value(val1)

current_control_set = reg.open("ControlSet001\\Control")
current_control_set_window = RegistryKeyMock("Windows", current_control_set)
current_control_set.add_child(current_control_set_window)

val2 = RegistryValueMock("ShutdownTime", b'\xe40\xa5!\xed\xf7\xd3\x01', RegBin)
current_control_set_window .add_value(val2)
return reg


@pytest.fixture
def mock_services():
interface1 = RegistryKeyMock.build("ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces\\{456A6A17D-21FC-123F-A689-A846D86EC008}")
reg = RegistryMock("SYSTEM", "system", interface1.root())
reg.set_ccs(1)

val1 = RegistryValueMock('DhcpIPAddress', '127.0.0.1', RegSZ)
interface1.add_value(val1)

interface2 = reg.open("ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces")
key_ip_address = RegistryKeyMock.build("{123ee342-7039-466e-9d20-806e6f6e6963}\\IPAddress").root().open("{123ee342-7039-466e-9d20-806e6f6e6963}")
interface2.add_child(key_ip_address)

val2 = RegistryValueMock('IPAddress', '127.0.0.2', RegSZ)
key_ip_address.add_value(val2)

return reg


def test_run(mock_software, mock_control, mock_services):
# SOFTWARE
p = plugin(mock_software, LoggerMock(), "SOFTWARE", "-")
results = list(p.run())

assert (len(results) == 3), "There should be 3 results."
assert (results[0].custom["value"] == "Install Date:\t\t2018-04-10T12:41:40Z"), \
"It should have returned 'Install Date:\t\t2018-04-10T12:41:40Z'"
assert (results[1].custom["value"] == "Registered Owner:\tSome Dude"), \
"It should have returned 'Registered Owner\tSome Dude'"
assert (results[2].custom["value"] == "Operating System:\tWindows 7 Professional"), \
"It should have returned 'Operating System:\tWindows 7 Professional'"

# SYSTEM Control path
p = plugin(mock_control, LoggerMock(), "SYSTEM", "-")
results = list(p.run())
assert (len(results) == 2), "There should be 2 results"
assert (results[0].custom["value"] == "Hostname:\t\tTestPC"), \
"It should have returned 'Hostname:\t\tTestPC'"
assert (results[1].custom["value"] == "Last Shutdown Time:\t2018-05-30T08:06:36.766026Z"), \
"It should have returned 'Install Date:\t2018-04-10T12:41:40Z'"

# SYSTEM services
p = plugin(mock_services, LoggerMock(), "SYSTEM", "-")
results = list(p.run())
assert (len(results) == 2), "There should be 2 results"
assert (results[0].custom["value"] == "IP Address:\t\t127.0.0.1"), \
"It should have returned 'IP Address:\t127.0.0.1'"
assert (results[1].custom["value"] == "IP Address:\t\t127.0.0.2"), \
"It should have returned 'IP Address:\t\t127.0.0.2'"
25 changes: 25 additions & 0 deletions tests/test_usersids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from .reg_mock import RegistryMock, RegistryKeyMock, RegistryValueMock, LoggerMock
from Registry.Registry import RegSZ
import pytest

from regrippy.plugins.usersids import Plugin as plugin

@pytest.fixture
def mock_reg():
key = RegistryKeyMock.build("Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\S-1-5-18")
reg = RegistryMock("SOFTWARE", "software", key.root())

val = RegistryValueMock("ProfileImagePath", "systemprofile", RegSZ)
key.add_value(val)

return reg


def test_usersids(mock_reg):
p = plugin(mock_reg, LoggerMock(), "SOFTWARE", "-")

results = list(p.run())
assert(len(results) == 1), "There should be a single result"
assert(results[0].custom["value"] == "systemprofile: S-1-5-18"), "systemprofile: S-1-5-18"


0 comments on commit 48bdb13

Please sign in to comment.