Skip to content

Commit

Permalink
updated README
Browse files Browse the repository at this point in the history
  • Loading branch information
ghost-ng committed Jan 25, 2024
1 parent c4049cf commit 99b1159
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 14 deletions.
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,60 @@ Slinger is a versatile tool designed for advanced network interactions and manip
- **System Information Gathering**: Gather detailed system information, including server disk information, logged-on users, and transport details.
- **Wrapper Commands**: Commands to edit port forwarding rules, view the windows firewall, ip information, etc
- **CLI System**: Slinger offers an exhaustively simple CLI complete with help entries
- **Query Performance Data**: (Experimental) Remotely query performance data like remote processes

```
🤠 (10.0.0.28):\\> ps
[*] Retrieving Processes List...
[!] Performance Data querying is experimental and is still under development
Name PID PPID Priority Threads Handles
------------------------- ----- ------ ---------- --------- ---------
Idle 0 0 0 1 0
System 4 0 8 81 740
mmc (uuid:wVWpou) 152 1868 6 19 824
conhost 172 248 6 2 54
cmd 248 2836 6 1 26
svchost (uuid:LE9JOF) 428 712 8 14 779
smss 440 4 11 2 52
csrss 524 516 13 8 231
csrss (uuid:ZHvV4L) 616 608 13 8 243
vpnagent 620 712 10 6 437
wininit 624 516 13 1 79
winlogon 652 608 13 2 157
services 712 624 9 6 258
lsass 720 624 9 6 694
svchost (uuid:HfKmym) 756 712 8 16 535
svchost 780 712 8 7 358
svchost (uuid:1ngQeO) 808 712 8 6 327
dwm 896 652 13 7 190
svchost (uuid:xqconX) 920 712 8 13 444
svchost (uuid:AwBbeG) 980 712 8 28 1000
rundll32 1076 980 10 5 204
svchost (uuid:a31ADo) 1092 712 8 15 379
spoolsv 1228 712 8 8 370
svchost (uuid:0wxSfV) 1260 712 8 6 118
svchost (uuid:Fwvb34) 1280 712 8 8 194
msdtc 1292 712 8 9 163
dns 1296 712 8 10 10224
svchost (uuid:tQ16ZP) 1392 712 8 10 253
VGAuthService 1432 712 8 2 114
vm3dservice 1480 712 8 2 88
vmtoolsd 1532 712 13 10 308
vm3dservice (uuid:rfz3k2) 1544 1480 13 2 85
svchost (uuid:i2Waqs) 1568 712 8 15 162
dllhost 1976 712 8 10 192
vmtoolsd (uuid:OXMvuj) 1996 2628 8 9 231
WmiPrvSE 2176 780 8 10 316
WmiPrvSE (uuid:elaPeM) 2312 780 8 7 234
taskhostex 2540 980 8 5 201
vpnui 2548 2952 8 6 356
Taskmgr 2580 2628 8 10 305
explorer 2628 2612 8 38 1304
taskeng 2836 980 8 3 115
ServerManager 2988 2548 8 8 430
mmc 3004 2628 8 19 403
[+] Proccesses with '(uuid:<random chars>)' have duplicate names but are unique processes
```

## Usage

Expand Down
File renamed without changes.
52 changes: 42 additions & 10 deletions src/slingerpkg/lib/dcetransport.py
Original file line number Diff line number Diff line change
Expand Up @@ -858,12 +858,13 @@ def _hQueryPerformaceData(self, object_num, arch=64):

print_debug("Counter Definitions: \n" + str(counter_definitions)) # correct up to here

# Bring the position to the beginning of the instances (or counters)
pos = object_start + object_type['DefinitionLength']


# Check if we have any instances
#print_info("NumInstances: " + str(object_type['NumInstances']))
if object_type['NumInstances'] > 0:
# Bring the position to the beginning of the instances (or counters)
pos = object_start + object_type['DefinitionLength']
print_debug(f"Found {str(object_type['NumInstances'])} instances")
# Parse the object instances and counters
for j in range(object_type['NumInstances']):
Expand Down Expand Up @@ -916,35 +917,65 @@ def _hQueryPerformaceData(self, object_num, arch=64):
# start at the end of the PERF_COUNTER_DEFINITIONS and PERF_OBJECT_TYPE
print_debug(f"Found {str(object_type['NumInstances'])} instances")

# Calculate the total length of all counter definitions
total_counter_definitions_length = sum(cd['ByteLength'] for cd in counter_definitions.values())

# Calculate the start position of the counter block
counter_block_start = object_start + object_type['HeaderLength'] + total_counter_definitions_length
initial_counter_block_pos = object_start + object_type['HeaderLength'] + total_counter_definitions_length

# Calculate padding if needed
padding_needed = (8 - (initial_counter_block_pos % 8)) % 8

# Final position of the PERF_COUNTER_BLOCK, considering padding for alignment
final_counter_block_pos = initial_counter_block_pos + padding_needed


print_debug("Counter Block Start: " + str(counter_block_start))
# these should be the same
print_debug("Object Start: " + str(object_start))
print_debug("Initial Counter Block Start: " + str(initial_counter_block_pos))
print_debug("Final Counter Block Start: " + str(final_counter_block_pos))
print_debug("Original Position: " + str(pos))

# Parse the PERF_COUNTER_BLOCK
status, pos, counter_block = parse_perf_counter_block_test(queryvalue_result[1], pos)
#https://learn.microsoft.com/en-us/windows/win32/api/winperf/ns-winperf-perf_counter_block

status, pos, counter_block = parse_perf_counter_block_test(queryvalue_result[1], final_counter_block_pos)
print_debug("Counter Block: " + str(counter_block))

if not status:
# Handle error
print_debug("Error parsing counter block", sys.exc_info())
return False, pos

print_debug("New Position: " + str(pos))

# Start parsing the counter data
print_debug("NumCounters: " + str(object_type['NumCounters']))



for k in range(object_type['NumCounters']):
counter_def = counter_definitions[k]
counter_name = result['title_database'][counter_definitions[k]['CounterNameTitleIndex']]

print_debug(f"#{k} Counter Name: " + str(counter_name))

print_debug(f"Counter Block Start: {counter_block_start + counter_def['CounterOffset']} = {counter_block_start} + {counter_def['CounterOffset']}")
counter_block_start = counter_block_start + counter_def['CounterOffset']

status, pos, counter_result = parse_perf_counter_data(queryvalue_result[1], counter_block_start, counter_def)
# Bring the pos to the start of the counter

#print_debug(f"Counter Block Start: {counter_block_start + counter_def['CounterOffset']} = {counter_block_start} + {counter_def['CounterOffset']}")
#counter_block_start = counter_block_start + counter_def['CounterOffset']

#status, pos, counter_result = parse_perf_counter_data(queryvalue_result[1], counter_block_start, counter_def)


# change position to start of counter block
counter_data_start = counter_block_start + counter_def['CounterOffset']

# Now set pos to this position
pos = counter_data_start

status, pos, counter_result = parse_perf_counter_data(queryvalue_result[1], pos, counter_def)

if not status:
# Handle error
print_debug("Error parsing counter", sys.exc_info())
Expand All @@ -960,10 +991,11 @@ def _hQueryPerformaceData(self, object_num, arch=64):


# Update pos after processing all counters
pos = counter_block_start + counter_block['ByteLength']
#pos = counter_block_start + counter_block['ByteLength']


print_debug("Exiting Counter Definitions Loop")



return True, pos, result
Expand Down
32 changes: 28 additions & 4 deletions src/slingerpkg/lib/msrpcperformance.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"""

def parse_perf_counter_data(data, pos, counter_definition):
print_debug("Counter Size: " + str(counter_definition['CounterSize']))
try:
# Define format strings
int32_fmt = '<I' # 32-bit unsigned integer
Expand Down Expand Up @@ -237,10 +238,33 @@ def parse_perf_counter_block(data, pos=0): # no need for 64 bit handling
print_debug("MSRPC: ERROR: Error unpacking data: {}".format(e), sys.exc_info())
return False, "Error unpacking data: {}".format(e), None

def parse_perf_counter_block_test(data, pos=0): # no need for 64 bit handling
result = {}
pos, result['ByteLength'] = unmarshall_int32(data, pos)
return True, pos, result
def parse_perf_counter_block_test(data, pos=0):
dword_fmt = '<I' # Little-endian format for DWORD

try:
byte_length, pos = struct.unpack_from(dword_fmt, data, pos)[0], pos + 4
except struct.error as e:
# Check if the buffer is too short for unpacking
required_length = pos + 4 # Needed length for DWORD
if len(data) < required_length:
padding_needed = required_length - len(data)
# Pad the data appropriately
data += b'\x00' * padding_needed
# Try unpacking again
try:
byte_length, pos = struct.unpack_from(dword_fmt, data, pos)[0], pos + 4
except struct.error as e:
# Handle error if unpacking still fails
print_debug(f"MSRPC: ERROR: Error unpacking data after padding: {e}", sys.exc_info())
return False, "Error unpacking data after padding", None
else:
# Handle other unpacking errors
print_debug(f"MSRPC: ERROR: Error unpacking data: {e}", sys.exc_info())
return False, "Error unpacking data", None

return True, pos, {'ByteLength': byte_length}



def remove_null_terminator(s):
# Remove common null terminator patterns from the end of the string
Expand Down

0 comments on commit 99b1159

Please sign in to comment.