我有一个真正的 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
)
看起来您走在正确的轨道上,但有些事情您可以改变和改进。
我没有测试这个,我只是更正了代码。
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 服务器。