Skip to content

Fix TS_ALL_PROCESSES_INFO parsing for RpcWinStationGetAllProcesses#2155

Open
alexisbalbachan wants to merge 2 commits intofortra:masterfrom
alexisbalbachan:tstool_parser_fix
Open

Fix TS_ALL_PROCESSES_INFO parsing for RpcWinStationGetAllProcesses#2155
alexisbalbachan wants to merge 2 commits intofortra:masterfrom
alexisbalbachan:tstool_parser_fix

Conversation

@alexisbalbachan
Copy link
Copy Markdown
Collaborator

This PR fixes #1816 by replacing the heuristic parsing of RpcWinStationGetAllProcesses with a proper NDR structure implementation based on the protocol spec. Since the response is now modeled according to the actual
TS_ALL_PROCESSES_INFO layout, the example code was also updated to use the corrected process and SID fields.

@anadrianmanrique anadrianmanrique self-assigned this Mar 19, 2026
@anadrianmanrique anadrianmanrique added the bug Unexpected problem or unintended behavior label Mar 19, 2026
Comment thread impacket/dcerpc/v5/tsts.py Outdated
Comment thread impacket/dcerpc/v5/tsts.py Outdated
@anadrianmanrique
Copy link
Copy Markdown
Collaborator

anadrianmanrique commented Mar 27, 2026

regarding getSid issue, on my tests, pSid has never been populated by the target. not clear to me when this condition changes. This code on the other hand is able to trigger the bug:

from impacket.dcerpc.v5 import tsts

resp = tsts.RpcWinStationGetAllProcessesResponse()
resp['pResult'] = 0
resp['pNumberOfProcesses'] = 1

arr = resp.fields['ppTsAllProcessesInfo'].fields['Data']
entry = tsts.TS_ALL_PROCESSES_INFO()

entry.fields['pTsProcessInfo'].fields['Data']['UniqueProcessId'] = 123
entry.fields['pTsProcessInfo'].fields['Data']['SessionId'] = 1

### Non-null SID pointer with valid SID bytes for SYSTEM (S-1-5-18) ###
entry['SizeOfSid'] = 12
entry.fields['pSid'].fields['Data']['Data'] = bytes([1,1,0,0,0,0,0,5,18,0,0,0])

arr['Data'] = [entry]
resp['ErrorCode'] = 1

parsed = tsts.RpcWinStationGetAllProcessesResponse(resp.getData())
print(parsed['ppTsAllProcessesInfo'][0].getSid())

Copilot AI review requested due to automatic review settings April 22, 2026 05:10
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes incorrect/heuristic parsing of RpcWinStationGetAllProcesses by modeling the response using the protocol’s NDR structures, and updates the example usage accordingly (addresses #1816 crash).

Changes:

  • Implement proper NDR structures for TS_ALL_PROCESSES_INFO and update RpcWinStationGetAllProcessesResponse to return parsed process entries.
  • Replace LDAP3-based SID formatting with local SID canonical formatting helper(s).
  • Update examples/tstool.py and add unit tests covering SID formatting and TS_ALL_PROCESSES_INFO.getSid().

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
impacket/dcerpc/v5/tsts.py Reworks RpcWinStationGetAllProcesses response parsing to use protocol-correct NDR structures; updates SID handling helpers.
examples/tstool.py Adapts tasklist/taskkill output to the new parsed structures and corrected image name / SID accessors.
tests/misc/test_tsts.py Adds regression tests for binary SID canonicalization and parsing of populated TS_ALL_PROCESSES_INFO SID pointers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/misc/test_tsts.py
Comment on lines +1 to +4
import unittest

from impacket.dcerpc.v5 import tsts

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new test module doesn’t include the standard Impacket test header/shebang seen in other tests/misc/test_*.py files (e.g., tests/misc/test_utils.py:1-10). Consider adding the same header here for consistency and licensing clarity.

Copilot uses AI. Check for mistakes.
Comment on lines 28 to 33

import struct
from datetime import datetime, timedelta
from ldap3.protocol.formatters.formatters import format_sid

from impacket.dcerpc.v5 import transport
from impacket.uuid import uuidtup_to_bin, bin_to_string, string_to_bin
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import struct appears to be unused after removing the heuristic parsing logic (no remaining struct. usages in this module). Consider removing this import to avoid lint/packaging issues and keep dependencies minimal.

Copilot uses AI. Check for mistakes.
Comment on lines 1346 to 1348
('KernelTime', LARGE_INTEGER),
('ImageNameSize', RPC_UNICODE_STRING),
('ImageNameSize', TS_UNICODE_STRING),
('BasePriority', LONG),
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field name ImageNameSize is misleading now that the type is TS_UNICODE_STRING and consumers are expected to call .getValue() to obtain the image name. Per the MS-TSTS / SYSTEM_PROCESS_INFORMATION layout this field represents the image name UNICODE_STRING, so consider renaming it to ImageName (and optionally keeping a backward-compatible alias) to avoid confusion for callers.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Unexpected problem or unintended behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TStool.py with low priv user on DC crashes

3 participants