使用 kerberos 身份验证在 python 中创建 WEF 模拟器

问题描述 投票:0回答:1

我有一个真正的 WEF/WEC 设置,其中有三台计算机:Windows Server、Windows 10 (WEF) 和 Windows 10 (WEC)。它像这样工作得很好......但我想要一个使用 python 和 kerbeos 身份验证的 WEF 模拟器。

我在 WEF 上安装了 Wireshark,只是为了看看它实际发送到 WEC 的内容,并且它似乎总是发送两个请求 第一个是使用 Kerberos 令牌进行身份验证(如您所见,它显示 HTTP 请求 1/2):

Hypertext Transfer Protocol
    POST /wsman HTTP/1.1\r\n
    Connection: Keep-Alive\r\n
    Content-Type: application/soap+xml;charset=UTF-16\r\n
     [truncated]Authorization: Kerberos <kerbeors token>
        GSS-API Generic Security Service Application Program Interface
    User-Agent: Microsoft WinRM Client\r\n
    Content-Length: 0\r\n
        [Content length: 0]
    Host: wec.com:8080\r\n
    \r\n
    [Full request URI: http://wec.com:8080/wsman]
    [HTTP request 1/2]
    [Next request in frame: 24]

第二个实际上是包含 XML 数据的一个(参见 HTTP 请求 2/2):

Hypertext Transfer Protocol
    POST /wsman HTTP/1.1\r\n
    Connection: Keep-Alive\r\n
    Content-Type: multipart/encrypted;protocol="application/HTTP-Kerberos-session-encrypted";boundary="Encrypted Boundary"\r\n
    User-Agent: Microsoft WinRM Client\r\n
    Content-Length: 3472\r\n
        [Content length: 3472]
    Host: wec.com:8080\r\n
    \r\n
    [Full request URI: http://wec.com:8080/wsman]
    [HTTP request 2/2]
    [Prev request in frame: 22]
    File Data: 3472 bytes

示例 xml 数据:

<s:Envelope
    xmlns:s="http://www.w3.org/2003/05/soap-envelope"
    xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"
    xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
    xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd">
    <s:Header>
        <a:To>http://wec.com:8080/wsman</a:To>
        <m:MachineID
            xmlns:m="http://schemas.microsoft.com/wbem/wsman/1/machineid" s:mustUnderstand="false">wef.wec.com
        </m:MachineID>
        <a:ReplyTo>
            <a:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
        </a:ReplyTo>
        <a:Action s:mustUnderstand="true">http://schemas.dmtf.org/wbem/wsman/1/wsman/Events</a:Action>
        <w:MaxEnvelopeSize s:mustUnderstand="true">512000</w:MaxEnvelopeSize>
        <a:MessageID>uuid:87AF6068-CB36-4B7C-8C4B-038D839CF904</a:MessageID>
        <w:Locale xml:lang="en-US" s:mustUnderstand="false" />
        <p:DataLocale xml:lang="en-US" s:mustUnderstand="false" />
        <p:SessionId s:mustUnderstand="false">uuid:1707AC9F-3D93-4B88-825C-B75403C72C7C</p:SessionId>
        <p:OperationID s:mustUnderstand="false">uuid:FA29F086-B795-4F4A-B825-8628BFB8F157</p:OperationID>
        <p:SequenceId s:mustUnderstand="false">1</p:SequenceId>
        <w:OperationTimeout>PT60.000S</w:OperationTimeout>
        <e:Identifier
            xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing">uuid:8e6f0ea4-1f4e-11ef-801a-616c6d617765
        </e:Identifier>
        <w:Bookmark>
            <BookmarkList>
                <Bookmark Channel="Application" RecordId="17256411" IsCurrent="true"/>
                <Bookmark Channel="Security" RecordId="1"/>
                <Bookmark Channel="System" RecordId="2470"/>
            </BookmarkList>
        </w:Bookmark>
        <w:AckRequested/>
    </s:Header>
    <s:Body>
        <w:Events>
            <w:Event Action="http://schemas.dmtf.org/wbem/wsman/1/wsman/Event">
                <Event
                    xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
                    <System>
                        <Provider Name='Microsoft-Windows-Security-SPP' Guid='{E23B33B0-C8C9-472C-A5F9-F2BDFEA0F156}' EventSourceName='Software Protection Platform Service'/>
                        <EventID Qualifiers='16384'>16384</EventID>
                        <Version>0</Version>
                        <Level>4</Level>
                        <Task>0</Task>
                        <Opcode>0</Opcode>
                        <Keywords>0x80000000000000</Keywords>
                        <TimeCreated SystemTime='2024-05-31T12:23:09.8605030Z'/>
                        <EventRecordID>17256409</EventRecordID>
                        <Correlation/>
                        <Execution ProcessID='0' ThreadID='0'/>
                        <Channel>Application</Channel>
                        <Computer>wef.wec.com</Computer>
                        <Security/>
                    </System>
                    <EventData>
                        <Data>2024-06-14T16:57:09Z</Data>
                        <Data>RulesEngine</Data>
                    </EventData>
                    <RenderingInfo Culture='en-US'>
                        <Message>Successfully scheduled Software Protection service for re-start at 2024-06-14T16:57:09Z. Reason: RulesEngine.</Message>
                        <Level>Information</Level>
                        <Task></Task>
                        <Opcode></Opcode>
                        <Channel></Channel>
                        <Provider>Microsoft-Windows-Security-SPP</Provider>
                        <Keywords>
                            <Keyword>Classic</Keyword>
                        </Keywords>
                    </RenderingInfo>
                </Event>
            </w:Event>
        </w:Events>
    </s:Body>
</s:Envelope>

我怎样才能用Python发送这个?这些都一一发送了,没用。这是我尝试过的最后一段代码,但 WEC 不接受它:

import requests
import kerberos
from requests_toolbelt.multipart.encoder import MultipartEncoder


def get_kerberos_token(service):
    __, krb_context = kerberos.authGSSClientInit(service)

    kerberos.authGSSClientStep(krb_context, "")
    negotiate_details = kerberos.authGSSClientResponse(krb_context)

    return negotiate_details


multipart_data = MultipartEncoder(
    fields={
        'part1': ('', '', 'application/HTTP-Kerberos-session-encrypted'),
        'part2': ('', xml_content, 'application/octet-stream')
    },
    boundary='Encrypted Boundary'
)

headers = {

    'Connection': 'Keep-Alive',
    'Content-Type': multipart_data.content_type,
    'User-Agent': 'Microsoft WinRM Client',
    'Host': '127.0.0.1:8080',
    'Authorization': f'Kerberos {get_kerberos_token()}'
}

response = requests.post(
    url='http://127.0.0.1:8080/wsman',
    data=multipart_data,
    headers=headers
)
python http python-requests http-post multipartform-data
1个回答
0
投票

看起来您走在正确的轨道上,但有些事情您可以改变和改进。

  1. kerberos.authGSSClientInit”需要服务。当您调用“kerberos.authGSSClientInit()”时,您需要正确提供“服务”。这通常看起来像 'HTTP@hostname' 因此函数 'get_kerberos_token()' 需要一个正确的服务字符串。
  2. 您直接使用 'kerberos' 库,这比使用 'requests-kerberos'
  3. 等更高级别的库更麻烦且更容易出错
  4. 调整“授权”标头以正确集成 Kerberos 令牌。

我没有测试这个,我只是更正了代码。

import requests
from requests_kerberos import HTTPKerberosAuth, OPTIONAL
from requests_toolbelt.multipart.encoder import MultipartEncoder

# Function to read XML content from an external file
# This function opens the specified XML file, reads the content, and returns it as a string
def read_xml_content(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        return file.read()

# Path to the external XML file
xml_file_path = 'event_data.xml'

# Read the XML content from the file
# This variable will hold the XML data read from the file
xml_content = read_xml_content(xml_file_path)

# Create a multipart encoder with the required boundary and fields
# This sets up the multipart form-data payload with the defined boundary and fields
multipart_data = MultipartEncoder(
    fields={
        'part1': ('', '', 'application/HTTP-Kerberos-session-encrypted'),
        'part2': ('', xml_content, 'application/octet-stream')
    },
    boundary='Encrypted Boundary'
)

# Set up headers
# In this section we define the headers required for the HTTP request
headers = {
    'Connection': 'Keep-Alive',
    'Content-Type': multipart_data.content_type,  # This is set to the content type from the multipart encoder
    'User-Agent': 'Microsoft WinRM Client',       # User-Agent string similar to what a Windows client might send
    'Host': '127.0.0.1:8080',  # Update as necessary for your specific server
}

# Initialize Kerberos authentication using requests-kerberos
# This initializes the Kerberos authentication handler to be used in the request
kerberos_auth = HTTPKerberosAuth(mutual_authentication=OPTIONAL)

# Perform the HTTP POST request
# This sends the POST request with the multipart data and the headers specified, and uses Kerberos authentication
response = requests.post(
    url='http://127.0.0.1:8080/wsman',  # Update as necessary with your specific endpoint
    data=multipart_data,
    headers=headers,
    auth=kerberos_auth  # The Kerberos authentication is handled here
)

# Check the response
# This checks the HTTP response status and prints appropriate messages based on the status
if response.status_code == 200:
    print("Request sent successfully!")
else:
    print(f"Failed to send request. Status code: {response.status_code}")
    print("Response content:", response.content)

我引入了 'read_xml.content(file_path)' 函数来从名为 'event_data.xml' 的外部文件读取 XML,我利用 'requests_kerberos' 来处理 Kerberos 身份验证。 'HTTPKerberosAuth' 处理 'Authorization' 标头;无需手动设置令牌。我删除了手动 Kreberos 令牌插入,让 'requests-kerberos' 处理它。我确保标头 'Authorization' 使用 'kerberos_auth' 实例来嵌入 Kerberos 令牌。这应该确保 WEF 客户端能够顺利地使用 Kerberos 身份验证,从而确保您的 HTTP 请求得到正确的身份验证并发送到 WEC 服务器。

© www.soinside.com 2019 - 2024. All rights reserved.