Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] IOCTLs with less than 10 decimal digits aren't found #15

Closed
eranzim opened this issue Mar 15, 2022 · 7 comments
Closed

[BUG] IOCTLs with less than 10 decimal digits aren't found #15

eranzim opened this issue Mar 15, 2022 · 7 comments
Assignees
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@eranzim
Copy link
Contributor

eranzim commented Mar 15, 2022

Describe the bug
Any IOCTL with a code that has less than 10 decimal digits (e.g. 0x222003) won't be found by the current code.

Expected behavior
All IOCTLs should be found

Desktop (please complete the following information):

  • OS and version: Windows 10 21H2 (19044.1586)
  • IDA version: IDA 7.7 SP1
  • DriverBuddyReloaded Version: latest (1.3)
  • Python Version: 3.9.5
@eranzim eranzim added the bug Something isn't working label Mar 15, 2022
@VoidSec VoidSec changed the title IOCTLs with less than 10 decimal digits aren't found. [BUG] IOCTLs with less than 10 decimal digits aren't found. Mar 25, 2022
@VoidSec VoidSec added the help wanted Extra attention is needed label Mar 26, 2022
@VoidSec VoidSec self-assigned this Mar 26, 2022
@VoidSec
Copy link
Owner

VoidSec commented Mar 26, 2022

Thank you for the report. The checks implemented in:

are present in order to significantly lower the false positives; at the moment the script is trying to decode IOCTLs only if an immediate value, with at least 10 digits, is found in a possible DispatchDeviceControl routine and the value does not belong to a known NTSTATUS.

While it's true for most of the IOCTL values I've encountered to be in a format like 9C4060D4h = 2621464788dec (10 digits), there are also valid IOCTL codes as 0x222004h = 2236420dec (7 digits).

Unfortunately, that's a silly problem as I was not able to find any convention/definition on Windows that states what is their minimum/maximum possible value they can have nor their minimum digits. AFAIK even 0x1 will be a valid IOCTL and will be decoded successfully:
image

I can think of removing/limiting the safeguard to exclude unprobable IOCTL code (e.g. 1/2 digits only) in the next release thus resulting in much higher false-positive rates

@VoidSec VoidSec changed the title [BUG] IOCTLs with less than 10 decimal digits aren't found. [BUG] IOCTLs with less than 10 decimal digits aren't found Mar 28, 2022
@eranzim
Copy link
Contributor Author

eranzim commented Mar 28, 2022

I'm not sure 0 is a legal device number... I mean generally you can probably do anything you want, but maybe you won't get as much 0s...
Looks like 0x10000 (== 65536) might be a good minimal value. Instead of number of digits, you could check 0x10000 <= value... Might be able to also limit value from above. According to this: https://github.com/h0mbre/ioctl.py/blob/master/ioctl.py , maximal device type is 0xf60 (though I don't know what is that repo based on)

@VoidSec
Copy link
Owner

VoidSec commented Mar 28, 2022

Umh, as per Microsoft guidelines:

DeviceType: Values of less than 0x8000 are reserved for Microsoft. Values of 0x8000 and higher can be used by vendors.

Unfortunately 0x10000 is a valid IOCTL and cannot be used to tell them apart:
image

I spoke with @hacksysteam as well as other kernel driver hackers and we didn't come up with any good way of finding IOTCL ranges; I'll keep trying and let you know the result :)

@eranzim
Copy link
Contributor Author

eranzim commented Apr 18, 2022

So maybe only check minimal value, i.e. anything greater than 0x10000 is valid? Maybe we can also check that the Access and Method values give valid enum values (I didn't check their width), but I think just starting with 0x10000 <= value is a good enough check for now (and an improvement to the current one).

@VoidSec VoidSec reopened this Apr 25, 2022
@VoidSec
Copy link
Owner

VoidSec commented Apr 25, 2022

At the moment it has been partially fixed in 96be3fa, It now includes all the IOCTL values with more than 2 digits. It will have a bit more false positives but hopefully nothing that will break

@eranzim
Copy link
Contributor Author

eranzim commented Apr 26, 2022

Why do you even need to calculate digits? Why not change the check to if value >= 0x10000 and value not in NTSTATUS.ntstatus_values:?

@VoidSec
Copy link
Owner

VoidSec commented Apr 26, 2022

You're right. I've just realized that you were using the value of 0x10000 as anything below will result in 0 as a device number.
Theoretically, 0 is an unknown device but I'll agree with you that using 0x10000 won't result in many false positives.
I'll make a new commit to reflect those changes.

fengjixuchui added a commit to fengjixuchui/DriverBuddyReloaded that referenced this issue Apr 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants