Logging of client commands, possible?

Dan Kaminsky dan at doxpara.com
Thu Mar 14 11:43:12 EST 2002


> i'd like to capture unencrypted ssh packets in
> pcap format, just like openbsd's isakmpd does.
> and add support to tcpdump and etherreal for
> interpreting these packet, this would make
> debugging simpler.

isakmpd can do this probably because it's linked so deeply with the OS and
the kernel; sshd never actually sees the raw packets and we probably don't
want to complete the engineering effort to let it.  It ain't unimaginable --
libpcap is a decently portable and usable library, and we'd simply have to
set it to sniff for packets sent to the appropriate host involving the
randomly selected local port number.  However, we certainly wouldn't want to
put this dependancy in generic builds of SSH.

Here's the code segments to add.  You probably want to fork off the sniffer.
I do note this is useless for us Cygwin types (oh what I would do for
libpcap to work right under Win32 *sigh*).

#include <pcap.h>

pcap_t         *pcap;   /* PCAP descriptor */
u_char         *packet; /* Our newly captured packet */
struct pcap_pkthdr pkthdr;      /* PCAP packet information structure */
struct bpf_program fp;  /* Structure to hold the compiled prog */
char            pfprogram[255];
char            dev[255];
int             immediate = 1;
int             promisc = 1;

/* set default interface to sniff on */
snprintf(dev, sizeof(dev), "%s", pcap_lookupdev(NULL));

/* create sniffer rule */
snprintf(pfprogram, sizeof(pfprogram), "host %s and port %i", host,
local_port);

/* Begin sniffing...fork here if ya like */

pcap = pcap_open_live(dev, 65535, promisc, 5, NULL);
if (pcap == NULL) {
   perror("pcap_open_live");
   exit(EXIT_FAILURE);
}
if (ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, &immediate)) {
//perror("Couldn't set BPF to Immediate Mode.");
}
/* Compile and set the filter program */
if (pcap_compile(pcap, &fp, pfprogram, 1, 0x0) == -1) {
   pcap_perror(pcap, "pcap_compile");
   exit(EXIT_FAILURE);
}
if (pcap_setfilter(pcap, &fp) == -1) {
   pcap_perror(pcap, "pcap_setfilter");
   exit(EXIT_FAILURE);
}

/* Get the next packet from the queue, */
while (1) {
   packet = (u_char *) pcap_next(pcap, &pkthdr);
   // do something with each packet, save to disk or parse or whatever.
}


Another approach is the ssldump method of using access to the private key to
drive the parser in a custom tcpdump variant; this doesn't work too well in
SSH because we actually have some forward secrecy to speak of :-)  We'd need
to find a way to allow the session key to be dumped, probably with an escape
sequence feeding into the base64 encoder function.  Launch the sniffer w/
that key as an argument and it'd be able to parse encrypted sessions.

Honestly though, best approach is just to support -c none as a compile time
switch, and justify it on the basis that it lets us better search for slow
corruption attacks *without* cipher armoring...

--Dan





More information about the openssh-unix-dev mailing list