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

Wrong offset used when checking Version string of .net metadata #1708

Closed
dangodangodango opened this issue May 14, 2022 · 2 comments
Closed

Comments

@dangodangodango
Copy link
Contributor

offset = metadata_root = pe_rva_to_offset(
pe, yr_le32toh(cli_header->MetaData.VirtualAddress));
if (!struct_fits_in_pe(pe, pe->data + offset, NET_METADATA))
return;
metadata = (PNET_METADATA) (pe->data + offset);
// Version length must be between 1 and 255, and be a multiple of 4.
// Also make sure it fits in pe.
md_len = yr_le32toh(metadata->Length);
if (md_len == 0 || md_len > 255 || md_len % 4 != 0 ||
!fits_in_pe(pe, pe->data + offset, md_len))
{
return;
}

int64_t metadata_root = pe_rva_to_offset(
pe, yr_le32toh(cli_header->MetaData.VirtualAddress));
if (!struct_fits_in_pe(pe, pe->data + metadata_root, NET_METADATA))
return false;
NET_METADATA* metadata = (NET_METADATA*) (pe->data + metadata_root);
if (yr_le32toh(metadata->Magic) != NET_METADATA_MAGIC)
return false;
// Version length must be between 1 and 255, and be a multiple of 4.
// Also make sure it fits in pe.
uint32_t md_len = yr_le32toh(metadata->Length);
if (md_len == 0 || md_len > 255 || md_len % 4 != 0 ||
!fits_in_pe(pe, pe->data + offset, md_len))
{
return false;
}

The above two places (line 1653 and line 1724) are checking whether metadata version string is fits in pe, Version string offset is pe->data + offset + sizeof(NET_METADATA), and size is md_len. But the above code checks the md_len bytes starting from offset (which is metadata_root)

The correct code should be as follows:

!fits_in_pe(pe, pe->data + offset + sizeof(NET_METADATA), md_len)

And in the function dotnet_is_dotnet, the variable offset is not updated to metadata_root, so in line 1653, offset is still the offset of CLI_HEADER, this is also a problem.

@dangodangodango
Copy link
Contributor Author

dangodangodango commented May 14, 2022

if (IS_64BITS_PE(pe))
{
if (yr_le16toh(OptionalHeader(pe, NumberOfRvaAndSizes)) <
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
return false;
}
else if (!(pe->header->FileHeader.Characteristics & IMAGE_FILE_DLL)) // 32bit
{
// Check first 2 bytes of the Entry point are equal to 0xFF 0x25
int64_t entry_offset = pe_rva_to_offset(
pe, yr_le32toh(pe->header->OptionalHeader.AddressOfEntryPoint));
if (offset < 0 || !fits_in_pe(pe, pe->data + entry_offset, 2))
return false;
const uint8_t* entry_data = pe->data + entry_offset;
if (!(entry_data[0] == 0xFF && entry_data[1] == 0x25))
return false;
}

And in line 1670, shouldn't it be entry_offset < 0 instead of offset < 0?

dangodangodango added a commit to dangodangodango/yara that referenced this issue May 14, 2022
@wxsBSD
Copy link
Collaborator

wxsBSD commented May 16, 2022

I think you're right. Any chance you plan to submit dangodangodango@ac71504 as a PR? I think it is the correct fix (but I haven't tested it to be honest).

dangodangodango added a commit to dangodangodango/yara that referenced this issue May 20, 2022
plusvic pushed a commit that referenced this issue May 28, 2022
* Fix issue #1708

* Add test case for #1708

Build a dotnet pe that triggers this issue:
https://github.com/dangodangodango/BadDotnetPe
BitsOfBinary pushed a commit to BitsOfBinary/yara that referenced this issue May 29, 2022
plusvic pushed a commit that referenced this issue Jun 30, 2022
* Fix issue #1708

* Add test case for #1708

Build a dotnet pe that triggers this issue:
https://github.com/dangodangodango/BadDotnetPe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants