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

kernelCTF: Add CVE-2024-41010_lts #126

Open
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

V4bel-theori
Copy link

No description provided.

Copy link

google-cla bot commented Aug 16, 2024

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@V4bel-theori V4bel-theori changed the title CVE-2024-41010 kernelCTF: Add CVE-2024-41010_lts Aug 22, 2024
@koczkatamas koczkatamas force-pushed the master branch 2 times, most recently from b2e2b9f to 43a5a81 Compare September 27, 2024 21:30
@koczkatamas koczkatamas force-pushed the master branch 3 times, most recently from 933028d to c111d81 Compare March 3, 2025 14:31
@koczkatamas koczkatamas force-pushed the master branch 13 times, most recently from 76d6b57 to bf0d68f Compare March 13, 2025 15:39
Copy link
Collaborator

@koczkatamas koczkatamas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey,

This is just a quick code quality review. We're planning to review the submissions more deeply (actually understanding what the exploit does) in two weeks.

In general, the code quality looks okay, sometimes it's not clear what's leaked or how calculations work. I've left a few comments.

We also have a draft style guide now. Please take a look and let us know if it's helpful for understanding our code quality expectations: https://google.github.io/security-research/kernelctf/style_guide.

Thanks for the submission and PR!

int fname_idx;
} xattr_node_leak;

xattr_node_leak nodes[0x4000/(0x40/0x8)];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you comment here what are you calculating here (is 0x40 a size of an object, which one, etc)?

You can also use #define <struct>_SIZE 0x40 to make the calculation easier to read.

See more details in our new (still draft) style guide.

int nodes_cnt = 0, nodes_front = 0;
for(int i=0; i < 0x4000/(0x40/0x8); i+=0x40/0x8)
{
if(leaks[0x17 + i] == 0x59 && leaks[0x14 + i] && leaks[0x15 + i] && leaks[0x16 + i] && leaks[0x18 + i])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment here what are you checking and which objects which fields are you reading here with 0x17 or where this comes from?

See more details in our new (still draft) style guide.


uint64_t vmemmap_base = (read_msgmsg_for_leak_vmemmap_base(0x300) >> 28) << 28;
uint64_t kheap_base = (((((uint64_t)nodes[nodes_front].xattr.rb_node.rb_right - 0x6000000) >> 28) - 0x10) << 28);
uint64_t longjump_victim_address = kbase + 0x2c51a40;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it's in the writeup, but please comment here that this is the address of the saved_rbp (and other) registers. You can also use #define for this address (as it changes per target, rationale for this is here in our style guide).

{
char *buf = read_msg_msgseg(spray_qids[i], MTYPE_PRIMARY, MSG_MSGSEG_KMALLOC_CG_64);

if( (((uint64_t *)(buf))[4] >> 48) == 0xffff)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please comment here what you are leaking from (buf)[4] exactly (which kernel symbol or which field of which object).

goto retry_1bit_off;
}

struct pipeio *pipes[0x1f8];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment here why did you choose to create exactly 0x1f8 pipes. Is it because of some limitation or making sure you are draining all freelists or ...?

activate_ops(pipes[i]);

uint64_t vmemmap_base = (read_msgmsg_for_leak_vmemmap_base(0x300) >> 28) << 28;
uint64_t kheap_base = (((((uint64_t)nodes[nodes_front].xattr.rb_node.rb_right - 0x6000000) >> 28) - 0x10) << 28);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment here please what you are leaking here, and how the calculation works. What value does xattr.rb_node.rb_right contain at this point? Just a random heap pointer? Why do you need the -0x10 part?

printf("[+] target: 0x%llx\n", nodes[nodes_front].xattr.name);

for(int i=0; i<0x1f8; i++)
write_pipe(pipes[i], ((char *)&longjump - (longjump_victim_address&0xfff)),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mention in a comment that because we have to write the whole page, and we cannot just write the longjump_victim_address, that's why this calculation is happening. Also it may worth mentioning that you are writing random, somewhat uncontrolled memory from your exploit's stack (the memory before longjump until the beginning of the page) to the kernel and why it does not cause any issues or crashes.

write(pip1[1], "step 3", 4);

/* ---------------------- heap oob read ---------------------------------- */
printf("[*] waiting for exit...\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment here what are you waiting for exactly (which kernel function to be run). More details about this is in the style guide.

write(pip1[1], "step 3", 4);

/* ---------------------- heap oob read ---------------------------------- */
printf("[*] waiting for exit...\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment here what are you waiting for exactly (which kernel function to be run). More details about this is in the style guide.

break;
if((leaks[i] & 0xffffffff80000000) == 0xffffffff80000000 && (leaks[i] & 0xffffffffffff0000) != 0xffffffffffff0000)
{
kbase = (((leaks[i] >> 24) - 1) << 24); // memory_stats+352
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the leaks contain memory_stats+352, do we know?

Maybe comment here that the calculation is based on that memory_stats assumed to be at the base address of 0xffffffff82xxxxx (in the case of this specific exploit 0xffffffff82c497c0) and you are calculating the kbase that its base address is 0xffffffff81000000, so this calculation do the 0xffffffff82c497c0 -> 0xffffffff81000000 shift.

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

Successfully merging this pull request may close these issues.

3 participants