githubEdit

shellcode injection

level 4

  • in this challenge, the shellcode should not contain "H". we can avoid "H" by xoring out the register and using mov with shorter registers.

.intel_syntax noprefix

.global _start

_start:
    call pwn
    .string "/flag"
    .byte 0x00
pwn:
    ; open(flag, 0)
    xor eax, eax
    xor esi, esi
    xor edx, edx
    xor r10d, r10d
    push [rsp]
    pop rdi
    mov sil, 0
    mov al, 2
    syscall
    ; sendfile(1, rax, 0, 0x100)
    xor edi, edi
    mov dil, 1
    mov sil, al
    mov dl, 0
    mov r10, 0x100
    mov al, 40
    syscall

level 5

  • we cannot use syscall in this challenge. opcode for syscall is 0f 05 in hex. so, we can hardcode 0e 05 bytes in shellcode and increment this byte during runtime.

level 6

  • similar to the last challenge, syscalls are not allowed, and the first 4095 bytes of the shellcode region is write protected, we can slide down this region using nop and then modify/write syscall opcode during runtime.

level 7

  • all fds (stdin, stdout, stderr) are closed before executing shellcode. so we can open another file for writing the flag.

flag will be stored in outflag in the current directory

level 8

  • have to write shellcode in just 18 bytes. cannot be multi staged because the memory region as write permission is removed after 18 bytes are read.

  • we can set real uid to 0 and then execute the shell script in current directly which is named "i" to save space. the reason we need setuid(0) is because execve will the run bash scripts with ruid, and ruid is 1000, unless we explicitly set it with setuid()

file i can have

other solutions that uses chmod are much better and elegant, but i did not know that chmod was a syscall when i wrote my shellcode.

level 9

  • every other 10 bytes in shellcode is modified with int3 instruction. strategy for this challenge is:

  • we are opening file f in the current. directory which is a symlink to /flag

level 10

  • shellcode will be treated as an array of 8 byte integer and sorted. this can be solved with either a very small shellcode (18 byte shellcode from challenge 8 works here). but we can also implement a very general strategy similar to level9:

last byte will be the msb hence, the array is already sorted.

level 11

this challenge is challenge 10 + close(stdin). our shellcode for last challenge doesn't involve a second stage. so shellcode from level 8 and level 10 works for this challenge as well.

level 12

  • every byte in this shellcode should be unique. we can use multi stage shellcode so that the first stage is very small and can made to be unique.

  • stage 2 is a generic shellcode. stage1:

stage2:

level 13

  • only 12 bytes :(

  • we can do this using chmod syscall:

level14

  • only 6 bytes?

  • not possible to craft independent shellcode in 6 bytes. we need to salvage what we have when we call the shellcode. also, the program does not strip write permission from the memory map, which means possibility for staged shellcode

  • this is the state of registers and memory when we call the shellcode.

  • rax is already zero, so we can call read.

  • memory region is in rdx, we can exchange rdx and rsi with xchg, so that rsi can point to shellcode mem region.

  • we can null rdi with xor. now we can read(0, mem_addr, some_large_value)

  • for stage2, we can use a generic shellcode with atleast 6 nops at the beginnning. stage1:

stage2:

Last updated