InfoSect's Month of Pointless Bugs (#30)

InfoSect, Canberra's hackerspace, regularly runs public group sessions to perform code review and vulnerability discovery. Over the next 30 days, I'll highlight the source code of 30 unknown vulnerabilities.

Bug #30

In fcrackzip:

int REGPARAM
check_unzip (const char *pw)
{
  char buff[1024];
  char path[1024];
  char escpw[256];
  int status;

  escape_pw (escpw, pw);
  path_for_shell (path, file_path[0]);

  sprintf (buff, "unzip -qqtP \"%s\" %s " DEVNULL, escpw, path); 

  status = system (buff);

#undef REDIR

  if (status == EXIT_SUCCESS)
    {
      printf("\n\nPASSWORD FOUND!!!!: pw == %s\n", pw);
      exit (EXIT_SUCCESS);
    }

  return !status;

}

Lets look at escape_pw():

char *
escape_pw (char *dest, const char *str)
{
  /* backslash shell special charatcers */

  char ch, *p = dest;
  size_t len = strlen(str);
  int i;

  for (i = 0; i < len; i++)
  {
    ch = str[i];

    switch (ch)
    {
    /* ASCII table order */
    case '"':
    case '$':
    case 0x27: /* single quote */
    case '\\':
    case '`':
      /* backslash special characters */
      *p++ = '\\';
      *p++ = ch;
      break;
    default:
      *p++ = ch;
    }
  }

  /* terminate string */
  *p = '\0';

  return dest;
}

It doesn't do any filtering or escaping on the - character. If we make a password begin with - we can make unzip think we are passing an option. This causes the system() command do something unexpected and not report the correct password unzipped the file.

Lets create a zip file with a password "--".

# fcrackzip --length 2-2 out.zip 
possible pw found: jW ()
possible pw found: oG ()
possible pw found: o[ ()
possible pw found: qo ()
possible pw found: rM ()
possible pw found: t7 ()
possible pw found: u- ()
possible pw found: x3 ()
possible pw found: zW ()
possible pw found: B7 ()
possible pw found: Dx ()
possible pw found: D% ()
possible pw found: HD ()
possible pw found: IK ()
possible pw found: J! ()
possible pw found: S: ()
possible pw found: TV ()
possible pw found: 0* ()
possible pw found: 2g ()
possible pw found: 5n ()
possible pw found: 6! ()
possible pw found: 9O ()
possible pw found: $o ()
possible pw found: %I ()
possible pw found: /J ()
possible pw found: )m ()
possible pw found: -2 ()
possible pw found: -- ()

It finds the password correctly. But you really want to use the -u option, otherwise you will get too many false positives.

# fcrackzip -u --length 2-2 out.zip 
#

It didn't detect it. A truly pointless bug.

Popular posts from this blog

Empowering Women in Cybersecurity: InfoSect's 2024 Training Initiative

C++ Memory Corruption (std::string) - part 4

Pointer Compression in V8