Gateway Cryptography

Hacking Impossible Tunnels Through Improbable Networks with OpenSSH et al.
By Dan Kaminsky, CISSP | http://www.doxpara.com/gwc3.ppt
This is not a talk about How To Crack OpenSSH, this is a talk about OpenSSH On Crack

Summary

This is not how to crack SSH.  This is SSH on crack.
1) How to get there from here
2) What to do once you get there
3) Making getting there easier

The Trinity Of Code

Useful
No reason to try
Usable
No reason to hurt
Well Written
No chance they’ll ever have it
If you want to know my theories on the superiority of userspace, ask me later.  

The Basics

Bringing people up to speed
This is not another talk about the wonders of a simple local port forward
What OpenSSH does
Forwards a shell (w/ transparent X support)
Forwards a single command (with full stdio)
Forwards a single TCP port
“All SSH forwards are non-exclusive and non-transparent figments of userspace”

SSH under Windows

1) Install Cygwin from www.cygwin.com
2) Create a shortcut to rxvt
C:\cygwin\bin\rxvt.exe -rv -sl 20000 -fn “Courier-12" -e /usr/bin/bash
bash doesn’t work under whistler yet, so use zsh if you want to retain your tab-completion sanity
3) Finally enjoy a usable Unix environment under Win32
Everything in this talk is cross platform, as long as you’ve made Windows cross to another platform

Forwarding Shells

ssh user@host
Encryption:  3DES/Blowfish/AES
Authentication: Password, RSA/DSA
Key Generation
ssh1: ssh-keygen
ssh2: ssh-keygen –t dsa
Key Authorization
ssh1: cat ~/.ssh/identity.pub | ssh user@host ‘umask 0600; mkdir .ssh; cat >> authorized_keys’
ssh2: cat ~/.ssh/id_dsa.pub | ssh user@host ‘umask 0600; mkdir .ssh; cat >> authorized_keys2’
Separate auth – so remember ssh -1 and ssh -2

Forwarding Commands

ssh user@host ls
ssh –t user@host top
Fully 8 bit clean for most commands, 
  supports (unclean) TTYs for anything that wants to redraw screen (like top) using –t
Full STDIO(stdin/stdout/stderr) support
Allows pipelines across multiple systems

Command Forwarding: CD Burning Over SSH

mkisofs reads in files and spits out a burnable image
cdrecord burns the image.
Normal CD Burning
mkisofs –JR files | cdrecord dev=#,#,# speed=# -
Remote CD Burning
mkisofs –JR files | ssh user@host cdrecord dev=#,#,# speed=# -
Remote CD Burning From Windows 
mkisofs.exe –JR files | ssh.exe user@host cdrecord dev=#,#,# speed=# -
Remote CD Burning From Windows For Users
Right Click On Files/Directories, Click Send To, Click CDR.
Under development; trivial to write

Command Forwarding: File Transfer w/o SCP

# GET
alicehost$ ssh alice@bobhost “cat file” > file

# PUT
falicehost$ cat file > ssh alice@bobhost “cat > file”

# LIST
alicehost$ ssh alice@bobhost “ls”

# MGET
alicehost$ ssh alice@bobhost “tar -cf - /etc” | tar -xf –

# RESUME GET
alicehost$ ssh alice@bobhost “tail –c 231244 file” >> file

Planning on implementing SFTP using nothing more than these commands
SCP is just annoying me more and more, though the syntax is temporarily more convenient

Forwarding Ports

ssh user@host -L8000:127.0.0.1:80
ssh user@host -R80:127.0.0.1:8000
Separates into “listener” vs. “location”
If local listens, the destination is relative to the remote location
If remote listens, the destination is relative to the local location

Limitations on Port Forwards

By default, only the systems directly hosting the listener can connect to it
Local forwards can be made public using the –g option, 
  but remote “gateway ports” must be enabled using GatewayPorts Yes
Destination locations are unrestricted

Accessing a Port Forward

Application Layer
Connect Directly to 127.0.0.1 or “localhost”
Operating System Layer (“systemspace”)
Pre-empt DNS lookup in hosts file
Unix:  /etc/hosts
Win95: \windows\hosts
WinNT: \WINNT\system32\drivers\etc\hosts
All forwards must be preannounced, and share the same IP (127.0.0.1)

Problem: Static Forwards Are Inflexible

Work decently only when:
Each port is only used once
Passes:
Mail(smtp, pop3, imap)
Simple Web(HTTP)
Fails: 
Web Surfing Multiple Sites (HTTP)
P2P File Transfer(Napster, Gnutella),
Ports are predictable in advance
Fails miserably
FTP, both Active and Passive

Solution:Dynamic Forwarding w/ SOCKS

ssh user@host -D1080

SOCKS4/5:  An in-band protocol header, nothing more, 
  that allows the client to very quickly tell a proxy server where its actual destination was
SOCKS4 is extraordinarily simple
~9 bytes from Client, 8 byte response, 
  and the client has informed the “proxy” where it actually wants to go!
“Library Preloads” are excessive
The idea:  Run a trivial SOCKS daemon in the ssh client; use it to redirect the destination of each channel.

Dynamic Forwarding: Application Support

Most major Windows applications support SOCKS proxies directly
Internet Explorer, CuteFTP, IM Clients, P2P Clients(Napster, Gnutella)
Dialpad (Voice over IP to a telephone for free over SSH!)
SocksCap32 can be used to “Socksify” remaining apps on Windows
Outlook Express, LeechFTP, Media Player, etc.
Unix applications can be reasonably socksified too

Dynamic Forwarding:Faults In The Hack

No Network Isolation
Though this, of course, is “trusting the client”, there’s still value 
  in a client itself volunteering to ignore all communications not through the VPN “solution”. 
No Unified Configuration and Management Interface
Fixable, should this become popular.

Dynamic Forwarding: THE BIG PROBLEM

Server Freeze
Most SSH servers will temporarily block(lock up) if you attempt 
  to open a channel to a host that either doesn’t exist or cannot be resolved
General purpose solutions to this get…ugly.
OpenSSH has fewer problems in this arena
OpenSSH has no inherent SOCKS client support – cannot easily connect to dynamic port forwards

ProxyCommand:

Blind Proxying w/ SSH

ssh -o 'ProxyCommand arbitrary_tool proxy %u %h %p' user@10.1.0.1

A ProxyCommand is an arbitrary tool that, after it finishes executing, 
  leads to an 8 bit clean path to an SSH daemon
OpenSSH's excuse for SOCKS support :-)
Allows end-to-end crypto through any 8bit clean link
Like SSL over HTTP Connect

Wire Mode: Facilitating Self-Proxying SSH

ssh user@proxy -Whost:22

ProxyCommand needs an 8 bit path
SSH exists to provide 8 bit paths
Correct Method: Open a local port forward, use glue code 
  to directly connect it to ttyless stdio code

Cheap Hack Method:  Translate –Whost:22 into “nc host 22”

Using netcat-based Wire Mode

ssh -o 'ProxyCommand ssh user@proxy "nc %h %p"' user@server

Completely unusable
Alternative Syntax Under Development

ssh –B proxy user@server
ssh proxy/user@server
Competes with:

ssh user@proxy
proxy$ ssh user@server
The PROXY authenticates
The PROXY decrypts
The PROXY is Internet accessible
If the Proxy gets hacked, the network is toast.

No Internet Accessible Bastion Proxy: Now What?

proxy$ ssh user@client -R2022:127.0.0.1:22
client$ ssh user@127.0.0.1 -o "HostKeyAlias	proxy" -L8000:www-internal:80

	or (in upcoming builds, hopefully)

	client$ 	ssh user@proxy/2022	-L8000:www-internal:80

Turns inability to trust into irrelevancy of trust
Negative:  “You can’t trust the addresses of x, y, or z!”
Positive: “It doesn’t matter if you think you’re talking to the addresses of x, y, or z.”
MUST CHECK HOSTKEY – it’ll work even if you don’t

Cross-Connecting Mutually Firewalled Hosts

server$ ssh proxyuser@proxy -R10022:127.0.0.1:22
client$	ssh -o 'ProxyCommand ssh proxyuser2@proxy ‘nc 127.0.0.1 10022'	user@server

			or in my syntax

client$ ssh proxyuser2@proxy/10022 user@server

Again, as long as IP addresses cannot be trusted, it doesn’t matter that you’re talking to the proxy and connecting through one of its ports.

Fixing Port Forwards:

Defaults
ssh -L143    -> ssh -L143:127.0.0.1:143
ssh -Lfoo    -> ssh -L22:foo:22
ssh -R2022:  -> ssh -R2022:127.0.0.1:22

Begin with a default of 22:127.0.0.1:22, do some moderately painful string parsing in C, 
  and actually end up with a decently compressed syntax
Would forwarding ranges be useful, i.e. ssh -L7000-7020 ?

Expanding Escape Syntax

noname# ~?
Supported escape sequences:

~.  - terminate connection
~R  - Request rekey (SSH protocol 2 only)
~^Z - suspend ssh
~#  - list forwarded connections
~&  - background ssh (when waiting for connections to terminate)
~?  - this message
~~  - send the escape character by typing it twice

(Note that escapes are only recognized immediately after newline.)
Eventual goal:  Port both ssh_config syntax and ssh command line syntax to the escape character mode
Allow on-demand things like activation of X forwarding

Secure SU: The Battle Against Direct Root

Most “security gurus” will decry direct root login
Holdover from the battle against admins doing everything as root
SU is a painless enough context switch
If it hurts to switch, people will just do it all as root
Advantages to being forced to switch accounts
Inertia
Emotion – significance of the action is emphasized
Accounting – logs show who used root
Even though it essentially reduces the security of the root account 
  to the security of the Alice account, even OpenBSD (2.7, at least) 
  still exhorts users not to ssh directly to root, and instead to use SU. 

Secure SU: The Near-Perfect Compromise

alicehost$   ssh alice@bobhost -t “su –l root”
or in my syntax
             ssh alice+root@bobhost
SSHD creates a secure execution environment when commands are explicitly specified
Shell configuration files not loaded
su, as a setuid app, can’t generally be traced by ordinary users
User logs in as normal, is safely prompted for the root password, 
  gets a root shell without having to “slum” in through insecure space

Secure SU: Developing: Individuated Root

Individual Public Keys For Root Access
Nobody learns root password
authorized_keys contains list of identities allowed to connect as root to the system
SSHD modified to log who connected to root
Scales to multiple security-critical accounts
Root can modify its own authorized_keys, but other accounts could 
  have root owned, root readable authorized_keys files.
Individual Root Accounts
Multiple accounts all set to same UID, but with different passwords
Alice_Root, Bob_Root, etc.
Really only works for root

SLIRP/PPTP over SSH: Starting with PPPD

PPPD:  Standard Unix PPP Server
Generally creates an interface on its host called ppp#
Sets up a bidirectional route—works as an infrastructure-level datapath
Addressing can be manually or automatically negotiated
Standard Dialup Protocol
Command Forwarding allows remote PPPD to cleanly talk to local PPPD, 
  thus creating a Host-To-Host VPN between two hosts
Requires root on both
“PPP over SSH”

SLIRP/PPTP over SSH: SLIRPing a way

SLIRP:  User Mode NAT
Written around 1995
Amazingly useful to this day—doesn’t require root!
Converts any 8 bit clean shell into a PPP server, NATs the incoming TCP/UDP/ICMP
  and opens the necessary sockets on the shell server
Command Forwarding SLIRP instead of PPPD into local PPPD requires root 
  on only one host, but only the host running PPPD gets an OS-level route
Useful, but dangerous--but you’re trusting the server not to replace SLIRP
  with a hacked version that gives them a path back through your ready-and-willing PPPD.

SLIRP/PPTP over SSH: PPP over PPTP

PPTP:  Point to Point Protocol
Encapsulates PPP(Layer 2) inside of a GRE(Layer 3) Tunnel, allowing TCP/UDP/ICMP(Layer 4) traffic to pass
Try not to wrap your brain around this
Created by Microsoft as a VPN Solution
Version one was…infamously flawed.  Version two is somewhat better, but not widely trusted.
Client ships with and is integrated into Windows 98/Me/2000
Stable Interface
Network Isolation
Good UI
SSH cannot forward GRE internally

SLIRP/PPTP over SSH: PoPToP Puts It Together

PoPToP:  Unix PPTP Daemon
Implements GRE encapsulation only
Doesn’t re-implement PPP!
Executes PPPD or SLIRP inside of GRE
Who says the daemon needs to be local?
End Result
Windows 98 connects to user bastion host using PPTP
PoPToP strips GRE header, goes to execute PPP daemon
SSH cleanly forwards a SLIRP command run as a user on a remote bastion host into PoPToP
Windows 98 isolates itself and experiences remote bastion host as a PPTP VPN gateway!

SLIRP/PPTP over SSH: HowTo

The really lazy way
Used when source is closed but the binary app shells out to some external binary
Really really lazy for PoPToP because it’s open source
mv /usr/bin/slirp slirp_binary
echo ‘#!/bin/sh’ >> /usr/bin/slirp
echo ‘ssh user@host slirp_binary’ >>
 /usr/bin/slirp;
The less lazy way
Modify PoPToP to execute ‘ssh user@host slirp’ instead of ‘slirp’;
Should be noted that there’s *no* authentication to this link inside the PPTP network
Conclusion
ssh is powerful
ssh is flexible
ssh is fun.
any questions?  any requests?
 
howto/sshoncrack.txt · Last modified: 2005/08/27 21:56 by bw
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki