Who writes their own FTP server? Buffer overflow exploit, time to detect!
We’ve got another set of source code, one with the vulnerability, and one without.
Comparing these, we can find the vulnerability is a non-checked strcpy.
Command parse_command(char *cmdstring)
{
Command cmd;
char *token;
token = strtok(cmdstring, "\n");
if (token == NULL) {
token = strtok(cmdstring," ");
}
else token = strtok(token, " ");
strcpy(cmd.command,token);
token = strtok(NULL," ");
if (token != NULL) {
strcpy(cmd.arg,token);
}
else *cmd.arg = 0;
return cmd;
}
The issue is that copying from token (the split string) to the cmd.command
, and to cmd.arg
has no bounds checking. It’ll copy anything up to \0
. This allows buffer overflow attacks.
Patching it, is quite simple, use strncpy
and set a limit.
Command parse_command(char *cmdstring)
{
Command cmd;
char *token;
token = strtok(cmdstring, "\n");
if (token == NULL) {
token = strtok(cmdstring," ");
}
else token = strtok(token, " ");
strncpy(cmd.command,token,4);
token = strtok(NULL," ");
if (token != NULL) {
strncpy(cmd.arg,token,511);
}
else *cmd.arg = 0;
return cmd;
}
Taking the 511 characters for the body/data, and the 4 characters for the command, we come to a max length of 515. Zero basing this gets to 514. This means that anything over 514 bytes is likely an attack attempt.
Snort allows us to check for a byte at position 514, and if it exists, it’s likely an attack. We also want to use the rawbytes flag, so we can work off the data of the packet.
alert tcp $EXTERNAL_NET any -> $HOME_NET 8021 (msg:"tinyftp vulnerability"; flow:to_server; isdataat:514,rawbytes; classtype:misc-attack; sid:1234560003;)