Merge remote-tracking branch 'origin/topic/jsiwek/fix-netbios-decode-bifs'

* origin/topic/jsiwek/fix-netbios-decode-bifs:
  Fixes to `decode_netbios_name` and `decode_netbios_name_type` BIFs
This commit is contained in:
Tim Wojtulewicz 2021-04-30 09:40:18 -07:00
commit ad67d810be
7 changed files with 114 additions and 34 deletions

View file

@ -6,48 +6,88 @@
##
## name: The encoded NetBIOS name, e.g., ``"FEEIEFCAEOEFFEECEJEPFDCAEOEBENEF"``.
##
## Returns: The decoded NetBIOS name, e.g., ``"THE NETBIOS NAME"``.
## Returns: The decoded NetBIOS name, e.g., ``"THE NETBIOS NAM"``. An empty
## string is returned if the argument is not a valid NetBIOS encoding
## (though an encoding that would decode to something that includes
## only null-bytes or space-characters also yields an empty string).
##
## .. zeek:see:: decode_netbios_name_type
function decode_netbios_name%(name: string%): string
%{
if ( name->Len() != 32 )
return val_mgr->EmptyString();
char buf[16];
char result[16];
const u_char* s = name->Bytes();
int i, j;
int length = 0;
for ( i = 0, j = 0; i < 16; ++i )
{
char c0 = (j < name->Len()) ? toupper(s[j++]) : 'A';
char c1 = (j < name->Len()) ? toupper(s[j++]) : 'A';
buf[i] = ((c0 - 'A') << 4) + (c1 - 'A');
}
char c0 = toupper(s[j++]);
char c1 = toupper(s[j++]);
for ( i = 0; i < 15; ++i )
{
if ( isalnum(buf[i]) || ispunct(buf[i]) ||
if ( c0 < 'A' || c0 > 'P' || c1 < 'A' || c1 > 'P' )
return val_mgr->EmptyString();
buf[i] = ((c0 - 'A') << 4) + (c1 - 'A');
if ( isalnum(buf[i]) || ispunct(buf[i]) || buf[i] == ' ' ||
// \x01\x02 is seen in at least one case as the first two bytes.
// I think that any \x01 and \x02 should always be passed through.
buf[i] < 3 )
result[i] = buf[i];
++length;
else
break;
}
return zeek::make_intrusive<zeek::StringVal>(i, result);
// The 16th byte indicates the suffix/type, so don't include it
if ( length == 16 )
length = 15;
// Walk back and remove any trailing spaces or nulls
for ( ; ; )
{
if ( length == 0 )
return val_mgr->EmptyString();
auto c = buf[length - 1];
if ( c != ' ' && c != 0 )
break;
--length;
}
return zeek::make_intrusive<zeek::StringVal>(length, buf);
%}
## Converts a NetBIOS name type to its corresponding numeric value.
## See https://en.wikipedia.org/wiki/NetBIOS#NetBIOS_Suffixes.
##
## name: The NetBIOS name type.
## name: An encoded NetBIOS name.
##
## Returns: The numeric value of *name*.
## Returns: The numeric value of *name* or 256 if it's not a valid encoding.
##
## .. zeek:see:: decode_netbios_name
function decode_netbios_name_type%(name: string%): count
%{
if ( name->Len() != 32 )
return val_mgr->Count(256);
const u_char* s = name->Bytes();
char return_val = ((toupper(s[30]) - 'A') << 4) + (toupper(s[31]) - 'A');
for ( auto i = 0; i < 32; ++i )
{
char c = toupper(s[i]);
if ( c < 'A' || c > 'P' )
return val_mgr->Count(256);
}
char c0 = toupper(s[30]);
char c1 = toupper(s[31]);
char return_val = ((c0 - 'A') << 4) + (c1 - 'A');
return zeek::val_mgr->Count(return_val);
%}