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;
}
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.