runtime backdooring

Transcription

runtime backdooring
HITR2600NLDB 2K12 EXCLUSIVE
RUNTIME BACKDOORING
$$$ FOR LULZ AND PROFIT $$$
blasty <[email protected]>
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