CTF-practice-evening:2014-03-24

From Technologia Incognita
Revision as of 20:41, 24 March 2014 by MRieback (talk | contribs)
Jump to: navigation, search
CTF-practice-evening:2014-03-24
Date 2014/03/24
Time
Location ACTA
Type Workshop
Contact Melanie

Capture The Flag evening - Part 11

  • 24 March, 2014 - 7 PM
  • Please bring along a laptop with you!!!

General CTF Info

Walkthrough: Minibomb

  • Brainsmoke is explaining how he solved the challenge 'Minibomb' during the Codegate CTF
  • Minibomb is a small setuid binary
    • This is probably a handmade binary written in assembler, Linux ELF, 32 bit
    • You can see the ELF header if you use file or hexdump
      • For more information about the ELF header (including the binary entry point, memory pages being loaded, executable text, etc..), you can use readelf
    • Objdump allows us to disassemble the binary
    • It's a static binary - there's no dynamic loader
      • Dynamic binaries have an interpreter section, with more LD-* things that need to be resolved
      • The kernel needs to tell where the binary starts
    • You could also use IDA, but that's overkill for this binary
  • If you run it with strace, you see a list of signals and system calls
    • It starts, does an old_mmap call (you can get lots of information from the arguments, including the starting address), an unman (looks like a stack address - bfxx if usually on the stack in 32 bits)
    • It does a write and read
    • If you send lots of A's, you get a segfault - this gives away that you have a bug here
    • You can do this in gdb to get more information
      • You can see that a fault happens on the address 0x41414141 - our input!
      • It's easy to get arbitrary code execution here
  • Because it's a small file, we can take a look at the disassembled code
    • We can see the memory map
    • You can get system call information by typing 'syscall mmap' - we can see 0x5a, which is the syscall instruction in the disassembly!
    • We should read up to understand the meanings of: %eax, %ebx, etc…
      • We can give 6 arguments with a system call
    • Next command: %ebp is the frame pointer for the function call frames - this is also for the old_mmap system call
    • The one argument is an array of six arguments - that is a pointer to that argument
    • Next command: int 0x80 is the system call command on x86
  • readelf shows us that we have both data and text - the binary executable is loaded into 2 pages, starting from the start of the binary until 4096 bits later
    • The kernel loads it into the virtual address
    • You can also see another offset, used for page alignment with memory (in chunks of 4096 bytes)
    • The address we see in the disassembly is the same as the address in readelf
    • We can also visualise this by looking again in hex dump
      • We can see the protection bits (1-read, 2-write, 3-both)
      • This correlates to the arguments that we see in strafe
  • We can do the same with all of the other system calls
    • We can see the mmap, memunmap, write, read, etc…
  • This binary is so small that we can decode the whole thing
  • We can see a function call that allocated 16 bytes on the stack, by subtracting it from the stack pointer
    • It moves syscall 4 (write) to another address (look in hex-dump)
    • This writes passcode to the output
    • It prints 10 bytes to stdout - (0x1)
    • It does a write and a system call
    • It does a read and a system call
    • But then does something strange - it uses the stack pointer as the buffer it reads to
      • This gives a stack buffer overflow - you can write a page full of data to the stack - but there's only 16 bytes allocated to this purpose
  • If we run it again with strace, without having it crash, it also calls close
    • You can also see this in the disassembly
    • It closes stdin (this is a problem if you want to do shellcode, since you can't send data through it anymore)
    • It then does a write again, and then says BOOM!!, and then returns
    • (The binary doesn't really have any use)
  • The 4 bytes can be rewritten
    • We can test this by sending a bunch of A's again
    • i.e. echo -n 'AAAADDDDCCCCEEEEF' | strace ./minibomb
    • The read in strace now looks weird, because it's saying EFAULT (bad address)
    • We can look at this more carefully in gdb
      • We can print the stack pointer: x/40x $sp
      • (This behaves differently inside and outside of GDB since aslr is turned off in gdb)
      • We can write until the end of the page, and then it will give a fault
      • A complication: The address space is randomised, so we don't know exactly where the stack is
    • You have arbitrary code execution for free, but the problem is that you can't inject your shellcode directly and run it, since there's a special section that determines if the writeable address space is being protected as non-executable
      • This is tells the kernel if the stack should be non-executable - in this case, the stack is both readable and writeable
      • Since it's RW, (not-executable) you'll need to use Return Oriented Programming (ROP)
      • This explains why the binary is so tiny - in this case, the amount of addresses to return to is very small (actually impossible)
      • This makes it much more difficult
    • Run this in gdb with lots of A's, and look in the registers: info reg
      • eax is 0xc = the number of bytes written
      • ecx is the buffer
      • edx is the number of bytes that it wanted to write
      • ebx the first argument
      • esp is the stack pointer
    • Do 'info proc map' in gdb to see the memory mapping
      • You can see the text, stack segments and the Virtual Dynamic Shared Object [vdso]
    • The mapped address spaces don't look randomised in gdb, so by default gdb turns aslr off
      • The first two are fixed addresses, the second two are usually randomised
      • We can jump to the fixed addresses - we just looked at this code with objdump
      • Example: x/20i <address>
    • The vdso is executable
      • If we look at that, (x/20s), we can see the ELF header
      • The data doesn't look very interesting at first
      • At a certain point, we can see symbols that the kernel needs to put into the address space (sigreturn and vsyscall)


Next CTF Competition

  • PlaidCTF: http://plaidctf.com and https://ctftime.org/event/119
    • April 11, 2014, 7 p.m. — April 13, 2014, 7 p.m. (Pittsburgh time)
    • We could meet on Saturday April 12 (all day) to play!
      • Alex is volunteering to host our CTF game at his apartment!
    • TODO Melanie: sign up Team Knuffelhackers