Defeating Timing Attacks Patch for OpenSSH 2.9.9p2 and 2.9p2
Nicolas Williams
Nicolas.Williams at ubsw.com
Wed Oct 17 07:36:18 EST 2001
Let's see. The timing attack has to do with predictable timing. The
solution would seem to be to add randomness to the packet timing. Your
patch does not do this -- it adds more predictable traffic.
I would think that to defeat the timing attack SSH would have to send
random-sized no-op packets at random intervals, or perhaps just adding
random delays before sending packets. And, of course, we're not talking
IP packets here, but SSH "packets."
But I could be wrong, I'm not an expert on this subject.
Nico
On Tue, Oct 16, 2001 at 12:21:00PM -0700, C. Jason Coit wrote:
> Hello,
>
> In response to the timing analysis attacks presented by Dawn Song et.
> al. in her paper http://paris.cs.berkeley.edu/~dawnsong/ssh-timing.html
> we
> at Silicon Defense developed a patch for openssh to avoid such
> measures.
>
> Timing Analysis Evasion changes were developed by C. Jason Coit and Roel
> Jonkman of Silicon Defense.
>
> These changes cause SSH to send packets unless request not to, exactly
> every 50 ms. IF no data is ready to be sent, SSH will send a bogus
> packet with 16 bytes of data (which is the same size as most
> keystrokes). Thus someone performing timing analysis cannot determine
> the inter keystroke timing of a user. SSH will send bogus data for
> about 1 second after the last keystroke. This both increases the
> difficulty of determining exact password lengths and conserves bandwidth
> when a user is idle (e.g. taking a coffee break). Both the Server and
> the Client exhibit this behavior and yet our code places no limit on the
> data rate(i.e. if the server needs to respond with large amounts of data
> it will be able to do so with large packets and without the 50 ms timing
> constraint).
>
> We currently have patches and modified distributions for OpenSSH 2.9p2
> and 2.9.9p2.
> The files for OpenSSH 2.9p2 are available at
> http://www.silicondefense.com/software/ssh/ssh-2.9p2-diffs
> http://www.silicondefense.com/software/ssh/opens3h-2.9p2.tar.gz
>
> These files for OpenSSH 2.9.9p2 are available at
> http://www.silicondefense.com/software/ssh/ssh-2.9.9p2-diffs
> http://www.silicondefense.com/software/ssh/opens3h-2.9.9p2.tar.gz
>
> The patch for 2.9.9p2 is available below:
>
> --- channels.c Mon Sep 17 22:53:12 2001
> +++ channels.new.c Mon Oct 15 14:28:43 2001
> @@ -25,6 +25,32 @@
> * 2. Redistributions in binary form must reproduce the above copyright
> * notice, this list of conditions and the following disclaimer in
> the
> * documentation and/or other materials provided with the
> distribution.
> +
> ***************************************************************************
> + *
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/13/2001.
> +
> ***************************************************************************
> *
> * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> @@ -1590,9 +1616,12 @@
>
>
> /* If there is data to send to the connection, enqueue some of it now.
> */
> -
> +/*
> + * SD Mod: add arguments bogus_send_count and
> use_steno_timing_manipulation
> + * to channel_output_poll.
> +*/
> void
> -channel_output_poll()
> +channel_output_poll(int *bogus_send_count, int
> use_steno_timing_manipulation)
> {
> int len, i;
> Channel *c;
> @@ -1649,11 +1678,49 @@
> SSH2_MSG_CHANNEL_DATA :
> SSH_MSG_CHANNEL_DATA);
> packet_put_int(c->remote_id);
> packet_put_string(buffer_ptr(&c->input),
> len);
> + /*
> + * Begin SD Mod: if using SSH2 and it
> is
> + * desired to use timing manipulation,
> reset
> + * counter since len > 0 implies packet
> will
> + * contain geniune data.
> + */
> + if(compat20 &&
> use_steno_timing_manipulation)
> + {
> + (*bogus_send_count)=0;
> + debug2("reseting count");
> + }
> + /* End SD Mod */
> packet_send();
> buffer_consume(&c->input, len);
> c->remote_window -= len;
> }
> - } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
> + }
> + /*
> + * Begin SD Mod:
> + * packet does not contain data, we are not in a
> draining
> + * state and timing manipulation is desired, check if
> bogus
> + * count is below threshold.
> + */
> + else if ((len = buffer_len(&c->input)) == 0
> + && !(c->istate == CHAN_INPUT_WAIT_DRAIN)
> + && use_steno_timing_manipulation)
> {
> + /*
> + * If we have not sent too many bogus packets, sent
> a 16
> + * byte ignore packet filled with garbage data and
> update
> + * the bogus_send_count;
> + */
> +
> + if((*bogus_send_count) < 20){
> + debug2("sending garbage packet");
> + packet_send_ignore(16);
> + packet_send();
> + (*bogus_send_count)++;
> + }
> + else
> + debug("max number of timeouts exceeded: stop
> sending garbage packets");
> + }
> + /* End SD Mod */
> + else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
> if (compat13)
> fatal("cannot happen: istate ==
> INPUT_WAIT_DRAIN for proto 1.3");
> /*
> --- channels.h Mon Sep 17 22:51:14 2001
> +++ channels.new.h Mon Oct 15 14:28:43 2001
> @@ -21,6 +21,33 @@
> * notice, this list of conditions and the following disclaimer in
> the
> * documentation and/or other materials provided with the
> distribution.
> *
> +
> ***************************************************************************
> + *
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/13/2001.
> +
> ***************************************************************************
> + *
> * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED.
> @@ -173,7 +200,15 @@
>
> void channel_prepare_select(fd_set **, fd_set **, int *, int*, int);
> void channel_after_select(fd_set *, fd_set *);
> -void channel_output_poll(void);
> +
> +/*
> + * SD Mod: added parameters bogus_send_count, and
> use_steno_timing_manipulation.
> + * The bogus_send_count keeps track of how many bogus packets have been
> sent since
> + * the last packet containing real data. The
> use_steno_timining_manipulation flag
> + * keeps track of whether to perform timing analysis evasion.
> + */
> +void channel_output_poll(int *bogus_send_count, int
> use_steno_timing_manipulation);
> +
>
> int channel_not_very_much_buffered_data(void);
> void channel_close_all(void);
> --- clientloop.c Mon Sep 17 22:51:14 2001
> +++ clientloop.new.c Mon Oct 15 14:28:43 2001
> @@ -46,6 +46,33 @@
> * notice, this list of conditions and the following disclaimer in
> the
> * documentation and/or other materials provided with the
> distribution.
> *
> +
> ***************************************************************************
> + *
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/13/2001.
> +
> ***************************************************************************
> + *
> * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED.
> @@ -315,16 +342,25 @@
> * Waits until the client can do something (some data becomes available
> on
> * one of the file descriptors).
> */
> -
> -static void
> +/*
> + * SD Mod: We changed the return value of
> client_wait_until_can_do_something
> + * from void to int. It now returns 1 if the steno_timer has expired
> and 0 if not.
> + */
> +int
> client_wait_until_can_do_something(fd_set **readsetp, fd_set
> **writesetp,
> int *maxfdp, int *nallocp, int rekeying)
> {
> + /* SD Mod: added variable steno_timer */
> + static struct timeval steno_timer = {0, 50000};
> +
> + int return_val = 0;
> + long int prev_timer_val = 0;
> +
> /* Add any selections by the channel mechanism. */
> channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
> rekeying);
>
> if (!compat20) {
> - /* Read from the connection, unless our buffers are
> full. */
> + /* Read from the connection, unless our buffers are full. */
> if (buffer_len(&stdout_buffer) < buffer_high &&
> buffer_len(&stderr_buffer) < buffer_high &&
> channel_not_very_much_buffered_data())
> @@ -342,13 +378,7 @@
> if (buffer_len(&stderr_buffer) > 0)
> FD_SET(fileno(stderr), *writesetp);
> } else {
> - /* channel_prepare_select could have closed the last
> channel */
> - if (session_closed && !channel_still_open()) {
> - if (!packet_have_data_to_write())
> - return;
> - } else {
> - FD_SET(connection_in, *readsetp);
> - }
> + FD_SET(connection_in, *readsetp);
> }
>
> /* Select server connection if have data to write to the server.
> */
> @@ -363,9 +393,34 @@
> * it: just have a random timeout for the select, and send a
> random
> * SSH_MSG_IGNORE packet when the timeout expires.
> */
> +
> + /*
> + * Begin SD Mod:
> + * Enforce wait send packets every 50 ms. To do this add timer
> to
> + * select loop. Buffer input as it comes and force the timer to
> decrement
> + * if select call does not do so.
> + */
> + prev_timer_val = steno_timer.tv_usec;
> +
> + return_val = select((*maxfdp)+1, *readsetp, *writesetp, NULL,
> &steno_timer);
>
> - if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0)
> {
> - char buf[100];
> + /* SD Mod continued:
> + * If the prev_timer_val is still equal to the
> steno_timer.tv_usec value
> + * then select did not decrement timer. So force decrement so
> timer can
> + * expire. This problem arises since the file descriptors change
> since they
> + * were reset just prior to entering the select loop. This is a
> strange
> + * fix but it works.
> + */
> +
> + if(prev_timer_val == steno_timer.tv_usec){
> + debug3("decrementing timer forcefully");
> + steno_timer.tv_usec -= 100;
> + }
> +
> + if(return_val < 0){
> + /* end of SD Mod */
> +
> + char buf[100];
>
> /*
> * We have to clear the select masks, because we return.
> @@ -376,14 +431,29 @@
> memset(*writesetp, 0, *maxfdp);
>
> if (errno == EINTR)
> - return;
> + return 0;
> /* Note: we might still have data in the buffers. */
> snprintf(buf, sizeof buf, "select: %s\r\n",
> strerror(errno));
> buffer_append(&stderr_buffer, buf, strlen(buf));
> quit_pending = 1;
> }
> + /*
> + * Begin SD Mod: Return to the caller whether the timer has
> + * expired or not. It is possible that the forced decrement
> caused
> + * the timer value to bbecome negative, if so the consider the
> + * timer expired, reset it and return 1 to the caller denoting
> timer
> + * expiration.
> + */
> + if(steno_timer.tv_usec <= 0)
> + {
> + steno_timer.tv_usec = 50000;
> + return 1;
> + }
> + else
> + return 0;
> + /* End SD Mod */
> +
> }
> -
> static void
> client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
> {
> @@ -773,6 +843,15 @@
> int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
> char buf[100];
>
> + /*
> + * Begin SD Mod:
> + * Add counter for number of fake packets that have been sent.
> + * Add time_out flag for marking when timeout has occured.
> + */
> + int bogus_send_count = 0;
> + int time_out = 0;
> + /* End SD Mod */
> +
> debug("Entering interactive session.");
>
> start_time = get_current_time();
> @@ -861,9 +940,16 @@
> * Make packets from buffered channel data, and
> * enqueue them for sending to the server.
> */
> - if (packet_not_very_much_data_to_write())
> - channel_output_poll();
> -
> + /*
> + * Begin SD Mod: on expiration of 50 ms timer
> call
> + * channel_ouput
> + */
> + if(time_out){
> +
> channel_output_poll(&bogus_send_count,options.use_steno_timing_manipulation);
> + time_out = 0;
> + }
> + /* End SD Mod */
> +
> /*
> * Check if the window size has changed, and
> buffer a
> * message about it to the server if so.
> @@ -878,8 +964,10 @@
> * available on one of the descriptors).
> */
> max_fd2 = max_fd;
> - client_wait_until_can_do_something(&readset, &writeset,
> - &max_fd2, &nalloc, rekeying);
> +
> + /* SD Mod: wait for data or timeout */
> + time_out = client_wait_until_can_do_something(&readset,
> + &writeset, &max_fd2, &nalloc,
> rekeying);
>
> if (quit_pending)
> break;
> @@ -1222,6 +1310,21 @@
> exit_status = packet_get_int();
> packet_done();
> }
> + /*
> + * Begin SD Mod:
> + * check to see if request from server is to turn off steno.
> + * If so, turn it off if neccessary.
> + */
> + else if (strcmp(rtype, "no_steno") == 0) {
> + debug("received request not use use steno");
> + if(options.use_steno_timing_manipulation)
> + {
> + options.use_steno_timing_manipulation = 0;
> + }
> + success = 1;
> + packet_done();
> + }
> + /* End SD Mod */
> if (reply) {
> packet_start(success ?
> SSH2_MSG_CHANNEL_SUCCESS :
> SSH2_MSG_CHANNEL_FAILURE);
> --- readconf.c Wed Sep 19 17:57:56 2001
> +++ readconf.new.c Mon Oct 15 14:28:43 2001
> @@ -9,6 +9,32 @@
> * software must be clearly marked as such, and if the derived work is
> * incompatible with the protocol description in the RFC file, it must
> be
> * called by a name other than "ssh" or "Secure Shell".
> + *
> +
> ***************************************************************************
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/3/2001.
> +
> ***************************************************************************
> */
>
> #include "includes.h"
> @@ -793,6 +819,12 @@
> options->preferred_authentications = NULL;
> options->bind_address = NULL;
> options->smartcard_device = NULL;
> + /*
> + * SD Mod: Initialize option to use steno timing manipulation.
> + * By default, timing analysis evasion is used. The -S flag
> + * must be used to turn off this feature.
> + */
> + options->use_steno_timing_manipulation = 1;
> }
>
> /*
> --- readconf.h Wed Sep 19 17:57:56 2001
> +++ readconf.new.h Mon Oct 15 14:28:43 2001
> @@ -9,6 +9,32 @@
> * software must be clearly marked as such, and if the derived work is
> * incompatible with the protocol description in the RFC file, it must
> be
> * called by a name other than "ssh" or "Secure Shell".
> + *
> +
> ***************************************************************************
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/3/2001.
> +
> ***************************************************************************
> */
>
> /* RCSID("$OpenBSD: readconf.h,v 1.39 2001/09/19 19:24:18 stevesk Exp
> $"); */
> @@ -101,6 +127,14 @@
> int num_remote_forwards;
> Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
> int clear_forwardings;
> +
> + /*
> + * SD Mod: Added option to use steno timing manipulation.
> + * By default, timing analysis evasion is used. The -S flag
> + * must be used to turn off this feature.
> + */
> + int use_steno_timing_manipulation;
> +
> } Options;
>
>
> --- servconf.c Wed Sep 12 09:32:15 2001
> +++ servconf.new.c Mon Oct 15 14:28:43 2001
> @@ -7,6 +7,32 @@
> * software must be clearly marked as such, and if the derived work is
> * incompatible with the protocol description in the RFC file, it must
> be
> * called by a name other than "ssh" or "Secure Shell".
> +
> ***************************************************************************
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/3/2001.
> +
> ***************************************************************************
> + *
> */
>
> #include "includes.h"
> @@ -105,6 +131,12 @@
> options->authorized_keys_file = NULL;
> options->authorized_keys_file2 = NULL;
> options->pam_authentication_via_kbd_int = -1;
> + /*
> + * SD Mod: Initialize option to use steno timing manipulation.
> + * By default, timing analysis evasion is used. The -S flag
> + * must be used to turn off this feature.
> + */
> + options->use_steno_timing_manipulation = 1;
> }
>
> void
> --- servconf.h Wed Sep 12 09:40:06 2001
> +++ servconf.new.h Mon Oct 15 14:28:43 2001
> @@ -9,6 +9,32 @@
> * software must be clearly marked as such, and if the derived work is
> * incompatible with the protocol description in the RFC file, it must
> be
> * called by a name other than "ssh" or "Secure Shell".
> +
> ***************************************************************************
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/3/2001.
> +
> ***************************************************************************
> + *
> */
>
> /* RCSID("$OpenBSD: servconf.h,v 1.49 2001/08/17 18:59:47 stevesk Exp
> $"); */
> @@ -129,7 +155,12 @@
> char *authorized_keys_file; /* File containing public keys
> */
> char *authorized_keys_file2;
> int pam_authentication_via_kbd_int;
> -
> + /*
> + * SD Mod: Added option to use steno timing manipulation.
> + * By default, timing analysis evasion is used. The -S flag
> + * must be used to turn off this feature.
> + */
> + int use_steno_timing_manipulation;
> } ServerOptions;
>
> void initialize_server_options(ServerOptions *);
> --- serverloop.c Mon Sep 17 22:53:13 2001
> +++ serverloop.new.c Mon Oct 15 14:28:43 2001
> @@ -21,6 +21,31 @@
> * 2. Redistributions in binary form must reproduce the above copyright
> * notice, this list of conditions and the following disclaimer in
> the
> * documentation and/or other materials provided with the
> distribution.
> +
> ***************************************************************************
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/13/2001.
> +
> ***************************************************************************
> *
> * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> @@ -167,15 +192,24 @@
> * have data or can accept data. Optionally, a maximum time can be
> specified
> * for the duration of the wait (0 = infinite).
> */
> -static void
> +
> +/*
> + * SD Mod:
> + * We changed wait_until_can_do_something's return value from void
> + * to int. It now returns 1 if the steno_timer has expired and 0 if
> not.
> + */
> +int
> wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int
> *maxfdp,
> int *nallocp, u_int max_time_milliseconds)
> {
> - struct timeval tv, *tvp;
> +
> + struct timeval tv, *tvp;
> + /* SD Mod: added variable steno_timer*/
> + static struct timeval steno_timer = {0, 50000};
> int ret;
> int client_alive_scheduled = 0;
> -
> - /*
> + long int prev_timer_val = 0;
> + /*
> * if using client_alive, set the max timeout accordingly,
> * and indicate that this particular timeout was for client
> * alive by setting the client_alive_scheduled flag.
> @@ -183,11 +217,11 @@
> * this could be randomized somewhat to make traffic
> * analysis more difficult, but we're not doing it yet.
> */
> - if (compat20 &&
> - max_time_milliseconds == 0 && options.client_alive_interval)
> {
> - client_alive_scheduled = 1;
> + if (max_time_milliseconds == 0 && options.client_alive_interval)
> {
> + client_alive_scheduled = 1;
> max_time_milliseconds = options.client_alive_interval *
> 1000;
> - }
> + } else
> + client_alive_scheduled = 0;
>
> /* When select fails we restart from here. */
> retry_select:
> @@ -199,7 +233,8 @@
> /* wrong: bad condition XXX */
> if (channel_not_very_much_buffered_data())
> FD_SET(connection_in, *readsetp);
> - } else {
> +
> +} else {
> /*
> * Read packets from the client unless we have too much
> * buffered stdin or channel data.
> @@ -250,8 +285,21 @@
> if (tvp!=NULL)
> debug3("tvp!=NULL kid %d mili %d", child_terminated,
> max_time_milliseconds);
>
> +
> + /* SD Mod: if select does not decrement timer, force it.*/
> + prev_timer_val = steno_timer.tv_usec;
> +
> + ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL,
> &steno_timer);
> +
> + if(prev_timer_val == steno_timer.tv_usec)
> + {
> + debug3 ("decrementing timer forcefully");
> + steno_timer.tv_usec -= 100;
> + }
> + /* End SD Mod */
> +
> /* Wait for something to happen, or the timeout to expire. */
> - ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
> +
>
> if (ret == -1) {
> if (errno != EINTR)
> @@ -259,9 +307,11 @@
> else
> goto retry_select;
> }
> +
> if (ret == 0 && client_alive_scheduled) {
> /* timeout, check to see how many we have had */
> - client_alive_timeouts++;
> +
> + client_alive_timeouts++;
>
> if (client_alive_timeouts >
> options.client_alive_count_max ) {
> packet_disconnect(
> @@ -282,9 +332,27 @@
> packet_disconnect(
> "No open channels after
> timeout!");
> }
> - }
> + }
> +
> + /*
> + * Begin SD Mod: Return to the caller whether the timer has
> + * expired or not. It is possible that the forced decrement
> caused
> + * the timer value to bbecome negative, if so the consider the
> + * timer expired, reset it and return 1 to the caller denoting
> timer
> + * expiration.
> + */
> + if(steno_timer.tv_usec <= 0)
> + {
> + steno_timer.tv_usec = 50000;
> + return 1;
> + }
> + else
> + return 0;
> + /* End SD Mod */
> +
> }
>
> +
> /*
> * Processes input from the client and the program. Input data is
> stored
> * in buffers and processed later.
> @@ -448,6 +516,13 @@
> u_int stdout_buffer_bytes;
> int type;
>
> + /*
> + * Begin SD Mod:
> + * NOT USED only here for compatibility with
> channel_output_poll().
> + */
> + int bogus_send_count = 0;
> + /* End SD Mod */
> +
> debug("Entering interactive session.");
>
> /* Initialize the SIGCHLD kludge. */
> @@ -549,8 +624,15 @@
> previous_stdout_buffer_bytes =
> buffer_len(&stdout_buffer);
>
> /* Send channel data to the client. */
> - if (packet_not_very_much_data_to_write())
> - channel_output_poll();
> + /*
> + * Begin SD Mod: use bogus_send_count to comply
> + * with channel_output_poll definition.
> + */
> + if(packet_not_very_much_data_to_write())
> + channel_output_poll(&bogus_send_count,0);
> + /*
> + * End SD Mod
> + */
>
> /*
> * Bail out of the loop if the program has closed its
> output
> @@ -579,7 +661,7 @@
> max_fd = MAX(max_fd, fderr);
>
> /* Sleep in select() until we can do something. */
> - wait_until_can_do_something(&readset, &writeset,
> &max_fd,
> + wait_until_can_do_something(&readset, &writeset,
> &max_fd,
> &nalloc, max_time_milliseconds);
>
> /* Process any channel events. */
> @@ -676,6 +758,14 @@
> int rekeying = 0, max_fd, status, nalloc = 0;
> pid_t pid;
>
> + /*
> + * Begin SD Mod:
> + * NOT USED only here for compatibility with
> channel_output_poll().
> + */
> + int bogus_send_count = 0 ;
> + int time_out = 0;
> + /* End SD Mod */
> +
> debug("Entering interactive session for SSH2.");
>
> mysignal(SIGCHLD, sigchld_handler);
> @@ -692,30 +782,44 @@
> process_buffered_input_packets();
>
> rekeying = (xxx_kex != NULL && !xxx_kex->done);
> -
> - if (!rekeying && packet_not_very_much_data_to_write())
> - channel_output_poll();
> - wait_until_can_do_something(&readset, &writeset,
> &max_fd,
> - &nalloc, 0);
> +
> + /*
> + * Begin SD Mod: send packets only when not rekeying and
> + * 50 ms timer has expired.
> + */
> + if (!rekeying && time_out)
> + {
> +
> channel_output_poll(&bogus_send_count,options.use_steno_timing_manipulation);
> + time_out = 0;
> + }
> +
> +
> + /*
> + * SD Mod: added time_out flag to record when
> + * 50 ms timer has expired.
> + */
> + time_out = wait_until_can_do_something(&readset,
> &writeset, &max_fd, &nalloc, rekeying);
> + /* End SD Mod */
> +
> if (child_terminated) {
> - while ((pid = waitpid(-1, &status, WNOHANG)) >
> 0)
> - session_close_by_pid(pid, status);
> - child_terminated = 0;
> + while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
> + session_close_by_pid(pid, status);
> + child_terminated = 0;
> }
> if (!rekeying)
> - channel_after_select(readset, writeset);
> + channel_after_select(readset, writeset);
> process_input(readset);
> if (connection_closed)
> - break;
> + break;
> process_output(writeset);
> }
> if (readset)
> - xfree(readset);
> + xfree(readset);
> if (writeset)
> - xfree(writeset);
> + xfree(writeset);
>
> mysignal(SIGCHLD, SIG_DFL);
> -
> +
> while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
> session_close_by_pid(pid, status);
> /*
> @@ -894,6 +998,17 @@
> packet_put_int(c->local_maxpacket);
> packet_send();
> }
> + /*
> + * SD Mod: if -S option is used, request
> + * client to not use stenographic timing manipulation as
> well.
> + */
> + if(!options.use_steno_timing_manipulation)
> + {
> + debug("sending no steno msg");
> + channel_request(c->remote_id,"no_steno",0);
> + }
> + /* End SD Mod */
> +
> } else {
> debug("server_input_channel_open: failure %s", ctype);
> packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
> --- session.c Sun Sep 16 15:17:15 2001
> +++ session.new.c Mon Oct 15 14:28:43 2001
> @@ -20,6 +20,32 @@
> * notice, this list of conditions and the following disclaimer in
> the
> * documentation and/or other materials provided with the
> distribution.
> *
> +
> ***************************************************************************
> + *
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/13/2001.
> +
> ***************************************************************************
> * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED.
> @@ -1726,6 +1752,24 @@
> return 1;
> }
>
> +
> +/*
> + * Begin SD Mod: This function is added to handle a request from the
> + * client to turn off steno timing manipulation.
> + */
> +int
> +session_no_steno_req(Session *s)
> +{
> + packet_done();
> + debug("handling steno request");
> + if(options.use_steno_timing_manipulation)
> + {
> + options.use_steno_timing_manipulation = 0;
> + }
> + return 1;
> +}
> +/* End SD Mod */
> +
> static int
> session_exec_req(Session *s)
> {
> @@ -1795,6 +1839,14 @@
> } else if (strcmp(rtype, "subsystem") == 0) {
> success = session_subsystem_req(s);
> }
> + /*
> + * Begin SD Mod: Handle request from the client
> + * to turn off server's timing manipulation.
> + */
> + else if (strcmp(rtype, "no_steno") == 0) {
> + success = session_no_steno_req(s);
> + }
> + /* End SD Mod */
> }
> if (strcmp(rtype, "window-change") == 0) {
> success = session_window_change_req(s);
> --- ssh.c Mon Sep 24 15:04:03 2001
> +++ ssh.new.c Mon Oct 15 14:28:43 2001
> @@ -26,6 +26,31 @@
> * notice, this list of conditions and the following disclaimer in
> the
> * documentation and/or other materials provided with the
> distribution.
> *
> + *
> ***************************************************************************
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/3/2001.
> +
> ***************************************************************************
> * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED.
> @@ -205,6 +230,8 @@
> fprintf(stderr, " -o 'option' Process the option as if it was
> read from a configuration file.\n");
> fprintf(stderr, " -s Invoke command (mandatory) as
> SSH2 subsystem.\n");
> fprintf(stderr, " -b addr Local IP address.\n");
> + /* SD Mod: */
> + fprintf(stderr, " -S Don't use stenographic timing
> manipulation\n");
> exit(1);
> }
>
> @@ -319,8 +346,9 @@
> host = NULL;
>
> again:
> + /* SD Mod: add s option to getopt() call */
> while ((opt = getopt(ac, av,
> - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
> + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:STVX")) != -1)
> {
> switch (opt) {
> case '1':
> options.protocol = SSH_PROTO_1;
> @@ -525,6 +553,14 @@
> case 's':
> subsystem_flag = 1;
> break;
> + /*
> + * Begin SD Mod: Add case to handle option to
> turn off
> + * steno timing manipulation.
> + */
> + case 'S':
> + options.use_steno_timing_manipulation = 0;
> + break;
> + /* End SD Mod */
> case 'b':
> options.bind_address = optarg;
> break;
> @@ -1080,6 +1116,20 @@
> channel_request_start(id, "auth-agent-req at openssh.com",
> 0);
> packet_send();
> }
> +
> + /*
> + * Begin SD Mod: If the client has the option to turn of timing
> + * manipulation set, send a request message to the server to
> + * turn off its timing manipulation.
> + */
> + if (!options.use_steno_timing_manipulation)
> + {
> + debug("sending request for no steno.");
> + channel_request_start(id, "no_steno",0);
> + packet_send();
> + }
> + /* End SD Mod */
> +
>
> len = buffer_len(&command);
> if (len > 0) {
> --- sshd.c Mon Sep 17 21:03:04 2001
> +++ sshd.new.c Mon Oct 15 14:28:43 2001
> @@ -26,6 +26,31 @@
> * 2. Redistributions in binary form must reproduce the above copyright
> * notice, this list of conditions and the following disclaimer in
> the
> * documentation and/or other materials provided with the
> distribution.
> + *
> ***************************************************************************
> + * Timing Analysis Evasion changes were developed by C. Jason Coit and
> Roel
> + * Jonkman of Silicon Defense.
> + *
> + * These changes cause SSH to send packets unless requested not to,
> exactly
> + * every 50 ms. If no data is ready to be sent, SSH will send a bogus
> packet
> + * with 16 bytes of data (which is the same size as most keystrokes).
> Thus
> + * someone performing timing analysis cannot determine the inter
> keystroke
> + * timing of a user. SSH will send bogus data for about 1 sec after
> the last
> + * keystroke. This both increases the difficulty of determing exact
> password
> + * lengths and conserves bandwith when a user is idle (e.g. taking a
> coffee break).
> + * Both the server and the client exhibit this behavior and yet our
> code places no
> + * limit on the data rate (i.e if the server needs to respond with
> large amounts
> + * of data it will be about to do so with large packets able to do so
> with large
> + * packets and without the 50 ms timing constraint).
> + *
> + * All changes were developed in response to timing analysis attack on
> ssh
> + * published by Dawn Song et. al.
> + *
> + * The evasion methods are only applicable to SSH2. All single line
> changes
> + * and small comments are marked by SD Mod. All multiline
> modifications are
> + * delimited by Begin SD Mod and End SD Mod.
> + *
> + * The last change was committed on 10/3/2001.
> +
> *******************************************************************************
> *
> * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> @@ -563,6 +588,7 @@
> initialize_server_options(&options);
>
> /* Parse command-line arguments. */
> + /* SD Mod: add s option to getopt() call */
> while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDeiqtQ46")) !=
> -1) {
> switch (opt) {
> case '4':
> @@ -645,6 +671,14 @@
> case 'u':
> utmp_len = atoi(optarg);
> break;
> + /*
> + * Begin SD Mod: Add option to handle option to
> turn off
> + * steno timing manipulation.
> + */
> + case 'S':
> + options.use_steno_timing_manipulation = 0;
> + break;
> + /* End SD Mod */
> case '?':
> default:
> fprintf(stderr, "sshd version %s\n",
> SSH_VERSION);
> @@ -665,6 +699,9 @@
> fprintf(stderr, " -u len Maximum hostname
> length for utmp recording\n");
> fprintf(stderr, " -4 Use IPv4 only\n");
> fprintf(stderr, " -6 Use IPv6 only\n");
> + /* SD Mod */
> + fprintf(stderr, " -S Don't use
> stenographic timing manipulation\n");
> +
> exit(1);
> }
> }
>
>
>
>
> --
> regards,
>
> Jason Coit
>
> +-- --+
> | C. Jason Coit Programmer/Analyst |
> | *Silicon Defense - Technical Support for Snort* |
> | http://www.silicondefense.com/ |
> +-- -+
--
Visit our website at http://www.ubswarburg.com
This message contains confidential information and is intended only
for the individual named. If you are not the named addressee you
should not disseminate, distribute or copy this e-mail. Please
notify the sender immediately by e-mail if you have received this
e-mail by mistake and delete this e-mail from your system.
E-mail transmission cannot be guaranteed to be secure or error-free
as information could be intercepted, corrupted, lost, destroyed,
arrive late or incomplete, or contain viruses. The sender therefore
does not accept liability for any errors or omissions in the contents
of this message which arise as a result of e-mail transmission. If
verification is required please request a hard-copy version. This
message is provided for informational purposes and should not be
construed as a solicitation or offer to buy or sell any securities or
related financial instruments.
More information about the openssh-unix-dev
mailing list