runtime backdooring
Transcription
runtime backdooring
HITR2600NLDB 2K12 EXCLUSIVE RUNTIME BACKDOORING $$$ FOR LULZ AND PROFIT $$$ blasty <blasty@fail0verflow.com> Saturday, September 8, 12 Who? • Hacker • Troll • Geek • 4 Ever Alone • Team Twiizers, TITAN, fail0verflow, EINDBAZEN, HITB CTF Saturday, September 8, 12 Abstract • Runtime debugging • Introducing a victim • Binary signature matching • Binary patching • Putting it all together • Live demo Saturday, September 8, 12 Disclaimer • Everything presented here is meant for educational and recreational purposes only. • A joke is a joke. (I hear blasty jokes alot) • We are here to discuss technology, not ethics. Saturday, September 8, 12 Apologiez • Techy stuff is techy • You can’t go from n00b -> 1337 in a day • Do not fear, the sourcecode is here! Saturday, September 8, 12 Runtime Backdooring irc x11 web 1337 hax0r ^- blasty cloud(tm) -^ [13:37] <blasty> w33blb0bz! [13:37] <blasty> oops.!@# [13:38] <hax0r_> h0h0!@ Saturday, September 8, 12 Runtime Backdooring blasty@x11:~$ ps x blasty 31054 0.0 blasty 16464 0.0 .. 0.0 104476 0.0 49952 4564 ? 6596 ? Ss Ss blasty@x11:~$ ./evil_backdoor 16464 /tmp/.klog [+] injecting keylogger into process 16464.. done! blasty@x11:~$ h3h3h3heHeheH3h.. h3h3h3heHeheH3h..: command not found blasty@x11:~$ tail -f /tmp/.klog id sudo su 3y3l0v3d0nk3yz! /etc/init.d/X11 restart ^C blasty@x11:~$ sudo su Password: 3y3l0v3d0nk3yz! root@x11:/home/blasty# id uid=0(root) gid=0(root) groups=0(root) root@x11:/home/blasty# j00 got owned son j00: command not found Saturday, September 8, 12 Sep02 Sep04 0:01 bash 0:00 xterm Debugging 101 “is he gonna talk about assembly and shit? my head hurts already!” Saturday, September 8, 12 Debuggers (lnx-x86_64) • GDB • ... • GDB!!!one • Toy Debuggers Saturday, September 8, 12 ptrace() #include <sys/ptrace.h> long ptrace( enum __ptrace_request request, pid_t pid, void *addr, /* target addr */ void *data /* local ptr */ ); • syscall (0x65 on Linux x86_64) • the one and only debugging interface exposed to userland Saturday, September 8, 12 7 primitives to rule the world • PTRACE_ATTACH • PTRACE_DETACH • PTRACE_GETREGS • PTRACE_SETREGS • PTRACE_PEEKTEXT • PTRACE_POKETEXT • PTRACE_SINGLESTEP Saturday, September 8, 12 Injecting Syscalls • PTRACE_GETREGS • backup regs to temp variable • rip=sc_addr, rax=sc_no, etc. • PTRACE_SETREGS (modified regs) • PTRACE_SINGLESTEP • PTRACE_SETREGS (restore original regs) • Syscall injected! Saturday, September 8, 12 Introducing a victim Saturday, September 8, 12 OpenSSH - the perfect victim • pretty much everyone uses this to admin *nix boxes • it’s a remotely exposed service that provides us with free crypto support • codebase is pretty clean for something written by hippies on LSD. Saturday, September 8, 12 Designing a patch • auth2-pubkey.c implements the public key authentication mechanism. • user_key_allowed() is the routine we want to attack. • user_key_allowed() invokes user_key_allowed2() to check if a pubkey is valid for the given user. • user_key_allowed2 eventually invokes key_equal() as it’s decision maker. • Ok, my head hurts _now_. Saturday, September 8, 12 Designing a patch (2) Saturday, September 8, 12 Troublez in 2012 • Ubuntu sshd ships as a stripped PIE executable. • fork()+execve()+ASLR = new memory layout for every sshd child Saturday, September 8, 12 SSHD Re-Exec • Every new ssh connection gets fork/clone’d of in a separate process image. • Not really an issue, except sshd nowadays also execve()’s itself for a completely new process image from disk. This introduces new ASLR mappings and destroys any patches we made in the parent, etc. • This makes patching code a pain. • It’s also the reason sshd needs to be invoked with it’s absolute path. Saturday, September 8, 12 SSHD Re-Exec (2) Saturday, September 8, 12 Stripped Binaries • Are a problem, we can’t do traditional (reliable) runtime symbol lookups • .. since the symbols have been stripped Saturday, September 8, 12 symbol_by_dbgstr() Saturday, September 8, 12 symbol_by_dbgstr() 48 8d 3d 32 f9 03 00 lea rdi Saturday, September 8, 12 offset 0x20b17+0x3f932+7=0x60450 symbol_by_dbgstr() • Find string in memory (“some string”) • Find code referencing pointer to string (lea) • Backtrace from code to routine prolog • ??? • PROFIT! Saturday, September 8, 12 /proc/pid/maps fastbox:~# ps x | grep /usr/sbin/sshd | head -n1 2198 ? Ss 0:26 /usr/sbin/sshd fastbox:~# cat /proc/2198/maps .. 7fa70d7e4000-7fa70d855000 r-xp 00000000 fe:00 108722 7fa70da55000-7fa70da57000 r--p 00071000 fe:00 108722 7fa70da57000-7fa70da58000 rw-p 00073000 fe:00 108722 7fa70da58000-7fa70da61000 rw-p 00000000 00:00 0 7fa70f4c3000-7fa70f4e4000 rw-p 00000000 00:00 0 7fffa51d9000-7fffa51ee000 rw-p 00000000 00:00 0 7fffa51ff000-7fffa5200000 r-xp 00000000 00:00 0 ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 * load address * permissions Saturday, September 8, 12 /usr/sbin/sshd /usr/sbin/sshd /usr/sbin/sshd [heap] [stack] [vdso] [vsyscall] Binary Patching • Due to ASLR mapping differences the hook-code needs to be patched with the correct function pointers. (key_equals, etc.) • We need some place to store our hook code. • We need to patch in a jump to the hook code from the place where the original key2_allowed() is invoked. Saturday, September 8, 12 Binary Patching We need some place to store our hook code. Syscall Injection to the rescue! void *mmap( void *addr, size_t length int prot, int flags, int fd, off_t offset ); Saturday, September 8, 12 mmap( 0x1337b00b0000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED, 0, 0 ); Binary Patching (2) Saturday, September 8, 12 Summing up.. • Determine sshd memory map by examining /proc/pid/maps • Look for a 0x0f,0x05 code sequence in the sshd memory .text (syscall instruction) • Do a lookup of rexec_flag through .dynsym • patch rexec_flag to 0 to prevent sshd from re-execing.. Saturday, September 8, 12 Summing up (2).. • Locate key_allowed, key_new, key_read, key_equal, key_free, restore_uid using the debug string to symbol technique. • Patch placeholder values in hook code with correct function pointers. • Find a hole in the memorymap close to the sshd .text section • Inject a mmap() syscall to allocate some memory for our hook code. Saturday, September 8, 12 Summing up (3).. • Find the ‘call key_allowed’ instruction in the sshd .text • Patch this instruction with a new E8???????? opcode that points to the start of the previously mmap()’d page. • ?? • PROFIT1 Saturday, September 8, 12 Live Demo! Saturday, September 8, 12 SSH Rape! https://github.com/blasty/ssh_rape.git Saturday, September 8, 12 Logo Submissions Saturday, September 8, 12 t4nkz 4 w@ch1ng!@# qu3st10nz? FR33 PLUG!@# FR33 PLUG!@# FR33 PLUG!@# HTTPS://WWW.CERTIFIEDSECURE.COM/ Saturday, September 8, 12