I'm trying to attach my Python program to this kernel level exe called "ntoskrnl.exe" and write to its memory.
However I'm unable to attach my program to "ntoskrnl.exe" via pymem or readwritememory and was wondering if someone could help me attach my program to "ntoskrnl.exe" and get its base address and write to it's memory.
I've so far tried pymem:
pm = pymem.Pymem("ntoskrnl.exe")
base = pm.base_address
and Readwritememory:
rwm = ReadWriteMemory()
process = rwm.get_process_by_name("ntoskrnl.exe")
both give me the process not found error! Any help on how to attach my program to the kernel level process and get it's base address would be greatly appreciated! Thanks
I've been trying this too. All I could find in regards so far is this:
def get_base_address(driver=None):
""" Returns base address of kernel modules """
if platform.architecture()[0] == "64bit":
lpImageBase = (c_ulonglong * 1024)()
lpcbNeeded = c_longlong()
psapi.GetDeviceDriverBaseNameA.argtypes = [c_longlong, POINTER(c_char), c_uint32]
else:
lpImageBase = (c_ulong * 1024)()
lpcbNeeded = c_long()
driver_name_size = c_long()
driver_name_size.value = 48
psapi.EnumDeviceDrivers(byref(lpImageBase), c_int(1024), byref(lpcbNeeded))
for base_addr in lpImageBase:
driver_name = c_char_p("\x00" * driver_name_size.value)
if base_addr:
psapi.GetDeviceDriverBaseNameA(base_addr, driver_name, driver_name_size.value)
if driver == None and driver_name.value.lower().find("krnl") != -1:
print("[+] Retrieving kernel info...")
print("[+] Kernel version: {:s}".format(driver_name.value))
print("[+] Kernel base address: {:#x}".format(base_addr))
return (base_addr, driver_name.value)
elif driver_name.value.lower() == driver:
print("[+] Retrieving {:s} info...".format(driver_name))
print("[+] {:s} base address: {:#x}".format(driver_name, base_addr))
return (base_addr, driver_name.value)
return None
get_base_address("ntoskrnl.exe")
I'm just happy that I'm not alone in the wild chase XD!
I am trying to write a script in python so I can find in 1 sec the COM number of the USB serial adapter I have plugged to my laptop.
What I need is to isolate the COMx port so I can display the result and open putty with that specific port. Can you help me with that?
Until now I have already written a script in batch/powershell and I am getting this information but I havent been able to separate the text of the COMx port so I can call the putty program with the serial parameter.
I have also been able to find the port via Python but I cant isolate it from the string.
import re # Used for regular expressions (unused)
import os # To check that the path of the files defined in the config file exist (unused)
import sys # To leave the script if (unused)
import numpy as np
from infi.devicemanager import DeviceManager
dm = DeviceManager()
dm.root.rescan()
devs = dm.all_devices
print ('Size of Devs: ',len(devs))
print ('Type of Devs: ',type(devs))
myarray = ([])
myarray =np.array(devs)
print ('Type of thing: ',type(myarray))
match = '<USB Serial Port (COM6)>' (custom match. the ideal would be "USB Serial Port")
i=0
#print (myarray, '\n')
while i != len(devs):
if match == myarray[i]:
print ('Found it!')
break
print ('array: ',i," : ", myarray[i])
i = i+1
print ('array 49: ', myarray[49]) (here I was checking what is the difference of the "element" inside the array)
print ('match : ', match) (and what is the difference of what I submitted)
print ('end')
I was expecting the if match == myarray[i] to find the two elements but for some reason it doesnt. Its returning me that those two are not the same.
Thank you for any help in advance!
=== UPDATE ===
Full script can be found here
https://github.com/elessargr/k9-serial
this is a follow up answer from #MacrosG
i tried a minimal example with properties from Device
from infi.devicemanager import DeviceManager
dm = DeviceManager()
dm.root.rescan()
devs = dm.all_devices
print ('Size of Devs: ',len(devs))
for d in devs:
if "USB" in d.description :
print(d.description)
If Python says the strings are not the same I dare say it's quite likely they are not.
You can compare with:
if "USB Serial Port" in devs[i]:
Then you should be able to find not a complete letter by letter match but one that contains a USB port.
There is no need to use numpy, devs is already a list and hence iterable.
If you want to do this with regular-expressions:
def main():
from infi.devicemanager import DeviceManager
import re
device_manager = DeviceManager()
device_manager.root.rescan()
pattern = r"USB Serial Port \(COM(\d)\)"
for device in device_manager.all_devices:
try:
match = re.fullmatch(pattern, device.friendly_name)
except KeyError:
continue
if match is None:
continue
com_number = match.group(1)
print(f"Found device \"{device.friendly_name}\" -> com_number: {com_number}")
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
Output:
Found device "USB Serial Port (COM3)" -> com_number: 3
Huge thanks to everyone and especially to bigdataolddriver since I went with his solution
Last thing!
for d in devs:
if "USB Serial Port" in d.description :
str = d.__str__()
COMport = str.split('(', 1)[1].split(')')[0]
i=1
break
else:
i=0
if i == 1:
print ("I found it!")
print(d.description, "found on : ", COMport)
subprocess.Popen(r'"C:\Tools\putty.exe" -serial ', COMport)
elif i ==0:
print ("USB Serial Not found \nPlease check physical connection.")
else:
print("Error")
Any ideas how to pass the COMport to the putty.exe as a parameter?
===== UPDATE =====
if i == 1:
print ("I found it!")
print(d.description, "found on : ", COMport)
command = '"C:\MyTools\putty.exe" -serial ' + COMport
#print (command)
subprocess.Popen(command)
Thank you everyone!
I am trying to read registry information from a modbus device using MinimalModbus. However, every time I attempt to read registry 40003 which has a value of 220 I receive this error:
raise ValueError('The slave is indicating an error. The response is: {!r}'.format(response))
ValueError: The slave is indicating an error. The response is: '\x01\x83\x02Àñ'
I know there is a value in 40003 and I am following the communication documents for the device. Here is my code:
import minimalmodbus
import serial
gas = minimalmodbus.Instrument('COM5', 1)
gas.serial.baudrate = 9600
gas.serial.bytesize = 8
gas.serial.parity = serial.PARITY_NONE
gas.serial.stopbits = 1
gas.serial.timeout = 0.05
gas.mode = minimalmodbus.MODE_RTU
temp = gas.read_register(40003, 1)
print (float(temp))
I have this problem for every registry and I cannot find information regarding Àñ.
The problem was the registry number 40003. I guess the modbus protocol doesn't require the full registry number, so I changed it to temp = gas.read_register(3, 1)
I need help is using serial port, I have 3DR radio telemetry connected to my python and other side to my windows PC ,I have small python code which continiously writes the data to serial port and reads , reading might not be an issue, or it might be later anyway...
The issue is i am afraid the too many writes might cause some buffer overflow, every time i search the solution is to enable rts/cts flow control, I dont know how to use it ?? what will happen if i set these then pyserial will do what and how can i control my write ?? its really confusing ..
hardware flow ccontol, I am not sure it might work, becuase I have just connected rx tx ground and power to my raspberry pi, even if try to connect the other flow control pins to pi, i am not sure it works or supported by 3dr radio telemetry.. I believe software flow control will be good and simple solution for now.
here is my code ..
for channel in list(self.__channelDict.values()):
# Addition for channel priority later
# We check if the channels in the list is active
if channel.getChannelActive() is True:
# Check if we have reached the max count
if (messageCount >= (self.__NoOfMessagesInUARTStream - 1)) or UARTForceSend:
self.sendUARTStream(UARTCacheBuffer, messageCount, UARTStreamCRC)
# Reset
messageCount = 0
UARTStreamCRC = 0
UARTCacheBuffer.emptyBuffer()
message = channel.RetriveMessage(queueType = 1, raw = True)
# # there is no TX message in this channel
if message is None:
continue # continue with next channel
else:
UARTStreamCRC = binascii.crc32(message, UARTStreamCRC)
UARTCacheBuffer.append(message, raw = True)
messageCount +=1
and the function to write to serial port
def sendUARTStream(self, UARTCacheBuffer, messageCount, UARTStreamCRC):
# retrieve all the data from the buffer and create a stream packet
UARTFrame = None # Used to forward the data
UARTStreamHeader = None
# Create the message header
if messageCount == 0:
# looks like all channels are empty
return 0
else:
messageArray = UARTCacheBuffer.getBuffer()
print(messageArray)
print('messageCount = ' + str(messageCount) + 'crc = ' + str(UARTStreamCRC))
UARTFrame[:self.__UARTStreamHeaderFormat.size] = self.createHeader(messageCount, UARTStreamCRC)
UARTFrame[self.__UARTStreamHeaderFormat.size : self.__UARTStreamHeaderFormat.size + self.__messageFormat * messageCount] = messageArray
# Its time to finally send the data
print('UARTFrame = ##' + str(UARTFrame))
self.__txPort.write(UARTFrame)
return messageCount
I try to write a Python program which calculates the WPA-handshake, but I have problems with the hashes. For comparison I installed cowpatty (to see where I start beeing wrong).
My PMK-generation works fine, but the PTK-calculation alsways seems to be wrong. I am not sure if I have to format my input (macadresses and noces) or just give them into the function as a string.
I will give you my routerinformation, which is no problem since I just set it up for testing.
My program looks as follows:
import hmac,hashlib,binascii
passPhrase = "10zZz10ZZzZ"
ssid = "Netgear 2/158"
A = "Pairwise key expansion"
APmac = "001e2ae0bdd0"
Clientmac = "cc08e0620bc8"
ANonce = "61c9a3f5cdcdf5fae5fd760836b8008c863aa2317022c7a202434554fb38452b"
SNonce = "60eff10088077f8b03a0e2fc2fc37e1fe1f30f9f7cfbcfb2826f26f3379c4318"
B = min(APmac,Clientmac)+max(APmac,Clientmac)+min(ANonce,SNonce)+max(ANonce,SNonce)
data="0103005ffe010900200000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
def customPRF512(key,A,B):
blen = 64
i = 0
R = ''
while i<=((blen*8+159)/160):
hmacsha1 = hmac.new(key,A+chr(0x00)+B+chr(i),sha)
i+=1
R = R+hmacsha1.digest()
return R[:blen]
pmk = pbkdf2(passPhrase, ssid, 4096, 32) #no sourcecode, since b2a_p(pmk) output fits to those of cowpatty
ptk = customPRF512(pmk,A,B) #the prf-function fits the pseudocode in the ieee, but does not give me the correct output (like cowpatty does)
# and i have no idea why :(
print b2a_p(pmk),"\n\n\n"
print b2a_p(ptk),"\n\n\n"
mic1 = hmac.new(ptk[0:16],data)
print mic1.hexdigest() #should be the mic-calculation, not sure if this is correct...
the desired outputs (which cowpatty confirmed) are:
PMK is
01b8 09f9 ab2f b5dc 4798 4f52 fb2d 112e
13d8 4ccb 6b86 d4a7 193e c529 9f85 1c48
Calculated PTK for "10zZz10ZZzZ" is
bf49 a95f 0494 f444 2716 2f38 696e f8b6
428b cf8b a3c6 f0d7 245a d314 a14c 0d18
efd6 38aa e653 c908 a7ab c648 0a7f 4068
2479 c970 8aaa abc3 eb7e da28 9d06 d535
Calculated MIC with "10zZz10ZZzZ" is
4528 2522 bc67 07d6 a70a 0317 a3ed 48f0
Maybe someone of you could tell me, why my program simply doesn't work. Do the hmac-functions work correctly? Is my input formatted wrong? Do I have to regard endianess anywhere? Thanks for your time in advance, I would appreciate any help!
Alright, I figured it out by myself... more by desperate testing and some luck, than successful research, which lead to nothing long enough. Instead of using the MAC-adresses and nonces as the strings they were, I had to unhexlify them. I used
a2b_hex() #alternatively unhexlify()
My final code looks somewhat like this, defs excluded:
import hmac,hashlib,binascii
passPhrase="10zZz10ZZzZ"
ssid = "Netgear 2/158"
A = "Pairwise key expansion"
APmac = a2b_hex("001e2ae0bdd0")
Clientmac = a2b_hex("cc08e0620bc8")
ANonce = a2b_hex("61c9a3f5cdcdf5fae5fd760836b8008c863aa2317022c7a202434554fb38452b")
SNonce = a2b_hex("60eff10088077f8b03a0e2fc2fc37e1fe1f30f9f7cfbcfb2826f26f3379c4318")
B = min(APmac,Clientmac)+max(APmac,Clientmac)+min(ANonce,SNonce)+max(ANonce,SNonce)
data = a2b_hex("0103005ffe01090020000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
pmk = pbkdf2(passPhrase, ssid, 4096, 32)
ptk = customPRF512(pmk,A,B)
mic = hmac.new(ptk[0:16],data)
print "desiredpmk:\t","01b809f9ab2fb5dc47984f52fb2d112e13d84ccb6b86d4a7193ec5299f851c48"
print "pmk:\t\t",b2a_hex(pmk),"\n"
print "desired ptk:\t","bf49a95f0494f44427162f38696ef8b6"
print "ptk:\t\t",b2a_hex(ptk[0:16]),"\n"
print "desired mic:\t","45282522bc6707d6a70a0317a3ed48f0"
print "mic:\t\t",mic.hexdigest(),"\n"
So the answers to my questions were: yes, hashfunctions work correctly, yes, input is formatted wrong, no, no endianess-issues.
Thanks for posting. This helped me out, so posting my revisions:
#==========================================================================================
#
# Verify the MIC code in EAPoL Message #2 is valid, or not (WPA2)
#
#==========================================================================================
#
# The home for this code is (so check for updates):
#
# https://www.duckware.com/tech/verify-mic-in-four-way-handshake.py.txt
#
# and this code is fully public, as it was based on/derived from this public code:
#
# https://stackoverflow.com/questions/12018920/wpa-handshake-with-python-hashing-difficulties
#
# 1. PMK: 'Pairwise Master Key' (256-bit) is generated from SSID/PASS in WPA2:
#
# o https://www.wireshark.org/tools/wpa-psk.html (SSID/PASS to PMK)
# o http://anandam.name/pbkdf2/ (Password-Based Key Derivation Function 2)
#
# 2. PRF512: The PRF-512 function is used to compute four 128-bit keys (KCK,KEK,TK1,TK2).
# For details on this function, see:
#
# o http://etutorials.org/Networking/802.11+security.+wi-fi+protected+access+and+802.11i/Part+II+The+Design+of+Wi-Fi+Security/Chapter+10.+WPA+and+RSN+Key+Hierarchy/Computing+the+Temporal+Keys/
#
# 3. KCK: The KCK (first 128 bits of the PTK; see above) are used to generate the MIC:
#
# o https://tldp.org/HOWTO/8021X-HOWTO/intro.html
#
# RUN: Run the code below in an ONLINE Python 2.7 compiler. For example:
#
# o https://repl.it/languages/python
# o https://www.tutorialspoint.com/execute_python_online.php
#
# CUSTOMIZE: How to customize the code below:
#
# 1) PCAP the problematic handshake (TIP: use tcpdump with ether host xx:xx:xx:xx:xx:xx)
# 2) Update SSID/PASS vars below with the known Wi-Fi name/password
# 3) Copy entire Ethernet frames for EAPoL Message #1/#2 into EAPOL1/2 vars below.
# TIP: In Wireshark, right click on Ethernet frame, 'Copy' / '...as a Hex Stream' / paste below
# 4) Use first with a working 4-way handshake (to confirm proper usage; MIC match), then apply
# to non-working 4-way handshake to confirm that the MIC in Message #2 is good/bad.
# 5) The code below, unmodified, results in a MIC found/calculated 'match'
#
# See also:
#
# o https://www.wifi-professionals.com/2019/01/4-way-handshake
# o https://stackoverflow.com/questions/15133797/creating-wpa-message-integrity-code-mic-with-python
# o https://www.shellvoide.com/wifi/understanding-wpa-wpa2-hash-mic-cracking-process-python/
# o https://ww.ins1gn1a.com/understanding-wpa-psk-cracking/
# o https://docs.python.org/3/library/binascii.html
# o https://stackoverflow.com/questions/9020843/how-to-convert-a-mac-number-to-mac-string
#
#==========================================================================================
import hmac,hashlib,binascii
def to_mac(addr): return ':'.join(addr[i:i+2] for i in range(0,len(addr),2))
def PRF_512(key,A,B): return ''.join(hmac.new(key,A+chr(0)+B+chr(i),hashlib.sha1).digest() for i in range(4))[:64]
def a2b(s): return binascii.a2b_hex(s);
def b2a(by): return binascii.b2a_hex(by);
EAPOL1 = a2b("60f189052d94a00460216606888e0203005f02008a00100000000000000001141f7a3ebdc0b51712934bef6e43ea13f80cb460f121f35408aa607046e239980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
EAPOL2 = a2b("a0046021660660f189052d94888e0103007502010a000000000000000000015b46c7165f504c664aed90b78f3b705e02b4b029a67e3189d1632479d7e7a4e6000000000000000000000000000000000000000000000000000000000000000056de18f5efa272a4663560b73c537a65001630140100000fac040100000fac040100000fac028000")
SSID = "your-wifi-ssid"
PASS = "your-wifi-password"
PMK = hashlib.pbkdf2_hmac('sha1', PASS, SSID, 4096, 32)
VER_WPA = 2 # WPA2 means use 'SHA1'
XAUTH = a2b("888E")
if EAPOL1[0:6]==EAPOL2[6:12] and EAPOL2[0:6]==EAPOL1[6:12] and EAPOL1[12:14]==XAUTH and EAPOL1[12:14]==XAUTH:
if ord(EAPOL1[20])%8==VER_WPA and ord(EAPOL2[20])%8==VER_WPA:
R1 = EAPOL1[31:63] # random 1 (AP nonce)
R2 = EAPOL2[31:63] # random 2 (STA nonce)
M1 = EAPOL2[0:6] # MAC 1 (AP MAC)
M2 = EAPOL1[0:6] # MAC 2 (STA MAC)
# Generate KCK, KEK, TK1, TK2 from the PMK (and AP/STA info)
PTK = PRF_512(PMK,"Pairwise key expansion",min(M1,M2)+max(M1,M2)+min(R1,R2)+max(R1,R2))
KCK = PTK[0:16];
# try to validate the MIC in EAPoL message #2 is correct
MICRAW = hmac.new(KCK,EAPOL2[14:95]+a2b("00000000000000000000000000000000")+EAPOL2[111:],hashlib.sha1)
MICFOUND = b2a(EAPOL2[95:111])
MICCALC = MICRAW.hexdigest()[0:32]
print "SSID/PASS: ",SSID,"/",PASS
print "PMK: ",b2a(PMK)
print "AP-MAC: ",to_mac(b2a(M1))
print "STA-MAC: ",to_mac(b2a(M2))
print "AP-NONCE: ",b2a(R1)
print "STA-NONCE: ",b2a(R2)
print "KCK: ",b2a(KCK)
print "MIC-found: ",MICFOUND
print "MIC-calc: ",MICCALC
print "Result: ",("OK: EAPoL message #2 validated" if MICFOUND==MICCALC else "ERROR: MIC does not match")
else:
print "***ERROR: Did not find expected 'WPA2' version in EAPoL messages"
else:
print "***ERROR: Problem validated Ethernet frames. Do EAPOL1 and EAPOL2 both include the Ethernet headers?"