fix: [validation] Correctly validate filename|tlsh attribute

pull/7901/head
Jakub Onderka 2021-10-29 12:49:16 +02:00
parent 339a594daf
commit 691ba360e0
2 changed files with 41 additions and 17 deletions

View File

@ -251,7 +251,7 @@ class AttributeValidationTool
$length = self::HASH_HEX_LENGTH[$type];
return __('Checksum has an invalid length or format (expected: %s hexadecimal characters). Please double check the value or select type "other".', $length);
case 'tlsh':
if (preg_match("#^t?[0-9a-f]{35,}$#i", $value)) {
if (self::isTlshValid($value)) {
return true;
}
return __('Checksum has an invalid length or format (expected: at least 35 hexadecimal characters, optionally starting with t1 instead of hexadecimal characters). Please double check the value or select type "other".');
@ -311,15 +311,22 @@ class AttributeValidationTool
return __('Checksum has an invalid length or format (expected: filename|%s hexadecimal characters). Please double check the value or select type "other".', $length);
case 'filename|ssdeep':
$composite = explode('|', $value);
if (strpos($composite[0], "\n") !== false) {
return __('Filename must not contain new line character.');
}
if (self::isSsdeep($composite[1])) {
return true;
}
return __('Invalid ssdeep hash (expected: blocksize:hash:hash).');
case 'filename|tlsh':
if (preg_match("#^.+\|[0-9a-f]{35,}$#", $value)) {
$composite = explode('|', $value);
if (strpos($composite[0], "\n") !== false) {
return __('Filename must not contain new line character.');
}
if (self::isTlshValid($composite[1])) {
return true;
}
return __('Checksum has an invalid length or format (expected: filename|at least 35 hexadecimal characters). Please double check the value or select type "other".');
return __('TLSH hash has an invalid length or format (expected: filename|at least 35 hexadecimal characters, optionally starting with t1 instead of hexadecimal characters). Please double check the value or select type "other".');
case 'filename|vhash':
if (preg_match('#^.+\|.+$#', $value)) {
return true;
@ -594,6 +601,19 @@ class AttributeValidationTool
return self::isPositiveInteger($value) && $value >= 1 && $value <= 65535;
}
/**
* @param string $value
* @return bool
*/
private static function isTlshValid($value)
{
if ($value[0] === 't') {
$value = substr($value, 1);
}
return strlen($value) > 35 && ctype_xdigit($value);
}
/**
* @param string $type
* @param string $value

View File

@ -22,6 +22,22 @@ class AttributeValidationToolTest extends TestCase
$this->shouldBeInvalid('filename|md5', [
'cmd.exe|86f7e437faa5a7fce15d1ddcb9eaeaea377667b8',
]);
$this->shouldBeValid('tlsh', [
'b2317c38fac0333c8ff7d3ff31fcf3b7fb3f9a3ef3bf3c880cfc43ebf97f3cc73fbfc',
't1fdd4e000b6a1c034f1f612f849b6a3a4b53f7ea1677481cf12d916ea4a79af1ed31317',
]);
$this->shouldBeValid('filename|tlsh', [
'cmd.exe|b2317c38fac0333c8ff7d3ff31fcf3b7fb3f9a3ef3bf3c880cfc43ebf97f3cc73fbfc',
'cmd.exe|t1fdd4e000b6a1c034f1f612f849b6a3a4b53f7ea1677481cf12d916ea4a79af1ed31317',
]);
$this->shouldBeValid('ssdeep', [
'96:s4Ud1Lj96tHHlZDrwciQmA+4uy1I0G4HYuL8N3TzS8QsO/wqWXLcMSx:sF1LjEtHHlZDrJzrhuyZvHYm8tKp/RWO',
'384:EWo4X1WaPW9ZWhWzLo+lWpct/fWbkWsWIwW0/S7dZhgG8:EWo4X1WmW9ZWhWH/WpchfWgWsWTWtf8',
'6144:3wSQSlrBHFjOvwYAU/Fsgi/2WDg5+YaNk5xcHrYw+Zg+XrZsGEREYRGAFU25ttR/:ctM7E0L4q',
]);
$this->shouldBeValid('filename|ssdeep', [
'ahoj.txt|96:s4Ud1Lj96tHHlZDrwciQmA+4uy1I0G4HYuL8N3TzS8QsO/wqWXLcMSx:sF1LjEtHHlZDrJzrhuyZvHYm8tKp/RWO',
]);
}
public function testValidateIp(): void
@ -64,18 +80,6 @@ class AttributeValidationToolTest extends TestCase
]);
}
public function testValidateSsdeep(): void
{
$this->shouldBeValid('ssdeep', [
'96:s4Ud1Lj96tHHlZDrwciQmA+4uy1I0G4HYuL8N3TzS8QsO/wqWXLcMSx:sF1LjEtHHlZDrJzrhuyZvHYm8tKp/RWO',
'384:EWo4X1WaPW9ZWhWzLo+lWpct/fWbkWsWIwW0/S7dZhgG8:EWo4X1WmW9ZWhWH/WpchfWgWsWTWtf8',
'6144:3wSQSlrBHFjOvwYAU/Fsgi/2WDg5+YaNk5xcHrYw+Zg+XrZsGEREYRGAFU25ttR/:ctM7E0L4q',
]);
$this->shouldBeValid('filename|ssdeep', [
'ahoj.txt|96:s4Ud1Lj96tHHlZDrwciQmA+4uy1I0G4HYuL8N3TzS8QsO/wqWXLcMSx:sF1LjEtHHlZDrJzrhuyZvHYm8tKp/RWO',
]);
}
public function testValidateDomainIp(): void
{
$this->shouldBeValid('domain|ip', [
@ -134,14 +138,14 @@ class AttributeValidationToolTest extends TestCase
private function shouldBeValid($type, array $values)
{
foreach ($values as $value) {
$this->assertTrue(AttributeValidationTool::validate($type, $value));
$this->assertTrue(AttributeValidationTool::validate($type, $value), "Value `$value` of type `$type` should be valid.");
}
}
private function shouldBeInvalid($type, array $values)
{
foreach ($values as $value) {
$this->assertNotTrue(AttributeValidationTool::validate($type, $value));
$this->assertNotTrue(AttributeValidationTool::validate($type, $value), "Value `$value` of type `$type` should be invalid.");
}
}
}