Skip to content

Add kernelCTF CVE-2025-38477_cos#268

Open
n132 wants to merge 74 commits intogoogle:masterfrom
n132:master
Open

Add kernelCTF CVE-2025-38477_cos#268
n132 wants to merge 74 commits intogoogle:masterfrom
n132:master

Conversation

@n132
Copy link

@n132 n132 commented Oct 21, 2025

No description provided.

@matrizzo
Copy link
Collaborator

As discussed on Discord, please try to make the exploit reproduce on the CI.

@n132
Copy link
Author

n132 commented Oct 24, 2025

As discussed on Discord, please try to make the exploit reproduce on the CI.

Thanks for the help. We'll try to make it more reliable on github action enviroment.

refcount issue into a UAF to make it more robust.


> Note on Original UAF Complexity: The original UAF primitive was also abandoned
Copy link
Collaborator

@artmetla artmetla Feb 24, 2026

Choose a reason for hiding this comment

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

Do I understand correctly that you decided to switch to another UaF primitive? If so, please rewrite the exploit.md to use correct one from the start. Starting from non-suitable or weak primitive obfuscates the logic and makes it harder to understand what is going on.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, we are converting it to another primitive since the difficulty we mentioned, "Race Window" was small.

We considered starting with the final primitive, and it's gonna be hard to explain why we write exploitation in such a complex way. We thought it might give the readers more helpful information to show the procedure for why we need to change to the final primitive. We also think the steps to get the final primitive are valuable to exploit hard race conditions (we admit it is too long, and readers may lose patience, but it is how a complex exploitation was built).

Copy link
Author

Choose a reason for hiding this comment

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

I believe the race condition in case 3/4 is one of the core technical contributions of this exploitation and the most distinctive part of this work. While the heap cross-cache techniques are important, they are already well covered in other write-ups. In contrast, the race condition angle is what makes this analysis unique (valuable) and provides deeper insight into the underlying issue.

Copy link
Author

Choose a reason for hiding this comment

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

Please let me know how you think. If you insist, I would like to focus on the last primitive and how heap exploitation works.

However, we got some good news!

- Window1.width = $769.94$ cycles
- Window2.width = $103.15$ cycles
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess it's worth clearly specify that you're converting Case 3 into Case 2 with interrupt insertion (mentioned in ExpRace Section)

Copy link
Author

Choose a reason for hiding this comment

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

Sorry again for the confusion that the wrong statement brings.

We can't transform from one case to another with ExpRace. ExpRace is enlarging the window to make an impossible case2/3 race condition possible to happen.

It's fixed in the comment: #268 (comment)
and fix: eb0b7aa

- Window2.width = $103.15$ cycles

This larger target window size (Window2) is critical because it greatly improves
the probability of a successful interrupt insertion (metioned in ExpRace
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
the probability of a successful interrupt insertion (metioned in ExpRace
the probability of a successful interrupt insertion (mentioned in ExpRace

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for correcting the typo. Fixed in: f51d45d

We began our investigation after our custom fuzzer triggered a null-dereference
crash. By understanding the root cause, we realized the crash was a result of a
Race Condition. After solving many challenges, we successfully transformed the
initial bug into a Use-After-Free (UAF) vulnerability, ultimately perfoming
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
initial bug into a Use-After-Free (UAF) vulnerability, ultimately perfoming
initial bug into a Use-After-Free (UAF) vulnerability, ultimately performing

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for correcting the typo. Fixed in: a653a87

Therfore, we can only use method 2 to create a UAF primitive. Considering that
we have to have one thread increase the refcount and another to decrease the
refcount, `qfq_change_agg` must be used to increase the refcount. Thus, we have
Thread 1 calling `qfq_chaneg_agg` and Thread 2 calling `qfq_delete_class`. There
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Thread 1 calling `qfq_chaneg_agg` and Thread 2 calling `qfq_delete_class`. There
Thread 1 calling `qfq_change_agg` and Thread 2 calling `qfq_delete_class`. There

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for correcting the typo. Fixed in: 3c29d4c


The net effect is that the true reference count has gone from $N$ to $N+1$ (by
Thread 1) and then back to $N-1$ (by Thread 2's overwrite), while the real agg
referrence counter is $N$. This achieves the target miscount: `Refcount ($N$) >
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
referrence counter is $N$. This achieves the target miscount: `Refcount ($N$) >
reference counter is $N$. This achieves the target miscount: `Refcount ($N$) >

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for correcting the typo. Fixed in: 8c8e15c

- What to write (solved by `NPerm`)

## UAF Unlink Attack Targeting Linked Lists: LL_ATK

Copy link
Collaborator

Choose a reason for hiding this comment

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

The exploit code does a lot of "Heap Feng Shui" like

  • XDP UMEM Spraying
  • Partial Slab Filling: The code uses partial_slab_obj loops to plug holes in the kmalloc-128 cache before triggering the vulnerability.
  • Warm-up Phases: The warm() function sends specific netlink messages to stabilize the heap state.

The write-up should include a section detailing the slab layout strategy. How did you ensure that the freed qfq_aggregate object was cleanly refilled with your payload so that hlist_del_init operated on attacker-controlled pointers?

Copy link
Author

Choose a reason for hiding this comment

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

  • I didn't use XDP for complex spraying. It's just for kmalloc-256 (It's cleaner than key, but we can use any other primitive).
  • Yes, I did use 0x8 (>=0x7) slabs to fill cpu partial
  • Warm-up is not for the heap but for caching. QEMU VM's first syscall is super slow and not stable, while winning the race requires it to be more stable/predictable. So we warm up.

I see it. I didn't include them since the heap layout is actually not complex (0x80*0x100 before + after, using CPU partial + huge page eviction skills).

I added some comments in exploit.c in: 56d5aa3
I'll add the explaination in the md file, too.

Copy link
Author

Choose a reason for hiding this comment

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

The heap related explaination is added in: 84bdead

@artmetla
Copy link
Collaborator

@n132 Thanks for the great and quick fixes. Please, modify/answer the rest of the question and I'll be ready to merge the PR.

@n132
Copy link
Author

n132 commented Feb 24, 2026

@n132 Thanks for the great and quick fixes. Please, modify/answer the rest of the question and I'll be ready to merge the PR.

Thanks so much for the detailed review. I'll work on these comments and inform you when they're done.

@n132
Copy link
Author

n132 commented Feb 25, 2026

Hi @artmetla, I resolved all the existing comments. Please let me know if these updates are still not clear. Thanks for your review again. Feel free to ask more questions. The exploit.c seems broken, but we can fix it later when there are no more style/format required changes on exploit.c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kCTF: vuln OK The submission exploits the claims vulnerability (passed manual verification)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants