This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients docs@python, eryksun, paul.moore, ronny-rentner, steve.dower, tim.golden, zach.ware
Date 2022-03-02.11:33:21
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1646220801.63.0.416649453804.issue46888@roundup.psfhosted.org>
In-reply-to
Content
Putting words into action, here's an example of what a privileged process (e.g. running as SYSTEM) can do if a script or application is written to call the undocumented NT API function NtMakePermanentObject(). A use case would be a script running as a system service that needs a shared-memory section object to persist after the service is stopped or terminated, e.g. such that the section is still accessible if the service is resumed. Anyway, this is just an example of what's possible, from a technical perspective. Also, note that I granted SeCreatePermanentPrivilege to my current user for this example, so it's certainly not required to use the SYSTEM account. An administrator can grant this privilege to any account.

By default, named kernel objects are temporary:

    >>> import os, _winapi, ctypes
    >>> from multiprocessing.shared_memory import SharedMemory
    >>> name = f'spam_{os.getpid()}'
    >>> m = SharedMemory(name, True, 8192)
    >>> m.close()
    >>> try: SharedMemory(name)
    ... except OSError as e: print(e)
    ...
    [WinError 2] The system cannot find the file specified: 'spam_6592'

Global permanent example:

Enable privileges for the current thread:

    >>> import win32api; from win32security import *
    >>> ImpersonateSelf(SecurityImpersonation)
    >>> da = TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES
    >>> ht = OpenThreadToken(win32api.GetCurrentThread(), da, False)
    >>> ps = [[0, SE_PRIVILEGE_ENABLED], [0, SE_PRIVILEGE_ENABLED]]
    >>> ps[0][0] = LookupPrivilegeValue(None, 'SeCreatePermanentPrivilege')
    >>> ps[1][0] = LookupPrivilegeValue(None, 'SeCreateGlobalPrivilege')
    >>> AdjustTokenPrivileges(ht, False, ps)
    ((16, 0),)

Create a global section object, and make it permanent:

    >>> name = rf'Global\spam_{os.getpid()}'
    >>> m = SharedMemory(name, True, 8192)
    >>> from win32con import DELETE
    >>> h = _winapi.OpenFileMapping(DELETE, False, name)
    >>> ntdll = ctypes.WinDLL('ntdll')
    >>> ntdll.NtMakePermanentObject(h)
    0
    >>> _winapi.CloseHandle(h)

A permanent object persists after the last handle is closed:

    >>> m.close()
    >>> m = SharedMemory(name) # This works now.

Make the section object temporary again:

    >>> h = _winapi.OpenFileMapping(DELETE, False, name)
    >>> ntdll.NtMakeTemporaryObject(h)
    0
    >>> _winapi.CloseHandle(h)
    >>> m.close()
    >>> try: SharedMemory(name)
    ... except OSError as e: print(e)
    ...
    [WinError 2] The system cannot find the file specified: 'Global\\spam_6592'
History
Date User Action Args
2022-03-02 11:33:21eryksunsetrecipients: + eryksun, paul.moore, tim.golden, docs@python, zach.ware, steve.dower, ronny-rentner
2022-03-02 11:33:21eryksunsetmessageid: <1646220801.63.0.416649453804.issue46888@roundup.psfhosted.org>
2022-03-02 11:33:21eryksunlinkissue46888 messages
2022-03-02 11:33:21eryksuncreate