diff --git a/nselib/msrpctypes.lua b/nselib/msrpctypes.lua index b230cb637..910ccc147 100644 --- a/nselib/msrpctypes.lua +++ b/nselib/msrpctypes.lua @@ -109,6 +109,7 @@ local os = require "os" local stdnse = require "stdnse" local string = require "string" local table = require "table" +local unicode = require "unicode" _ENV = stdnse.module("msrpctypes", stdnse.seeall) local REFERENT_ID = 0x50414d4e @@ -125,7 +126,6 @@ local ALL = 'ALL' --@return The unicode version of the string. function string_to_unicode(string, do_null) local i - local result = "" stdnse.print_debug(4, "MSRPC: Entering string_to_unicode(string = %s)", string) @@ -143,19 +143,16 @@ function string_to_unicode(string, do_null) end - -- Loop through the string, adding each character followed by a char(0) - for i = 1, #string, 1 do - result = result .. string.sub(string, i, i) .. string.char(0) - end + local result = unicode.utf8to16(string) -- Add a null, if the caller requested it if(do_null == true) then - result = result .. string.char(0) .. string.char(0) + result = result .. "\0\0" end -- Align it to a multiple of 4, if necessary if(#result % 4 ~= 0) then - result = result .. string.char(0) .. string.char(0) + result = result .. "\0\0" end stdnse.print_debug(4, "MSRPC: Leaving string_to_unicode()") @@ -173,48 +170,28 @@ end --@return (pos, string) The new position and the string read, again imitating bin.unpack. If there was an -- attempt to read off the end of the string, then 'nil' is returned for both parameters. function unicode_to_string(buffer, pos, length, do_null) - local i, j, ch, dummy - local string = "" - stdnse.print_debug(4, "MSRPC: Entering unicode_to_string(pos = %d, length = %d)", pos, length) - if(do_null == nil) then - do_null = false + local endpos = pos + length * 2 - 1 + + if endpos > #buffer then + stdnse.print_debug(1, "MSRPC: ERROR: Ran off the end of a string in unicode_to_string(), this likely means we are reading a packet incorrectly. Please report! (pos = %d, #buffer = %d, endpos = %d)", pos, #buffer, endpos) + + return nil, nil end - if(do_null == true and length > 0) then - length = length - 1 + local str = unicode.utf16to8(string.sub(buffer, pos, endpos)) + + if do_null then + str = string.sub(str, 1, -2) -- Eat the null terminator end - for j = 1, length, 1 do - - pos, ch, dummy = bin.unpack(" 0 ) and to_unicode(domain) or "" + local hostname = unicode.utf8to16("nmap") + username = unicode.utf8to16(username) + domain = (#username > 0 ) and unicode.utf8to16(domain) or "" ntlm = (#username > 0 ) and ntlm or "" lanman = (#username > 0 ) and lanman or string.char(0) @@ -763,7 +743,7 @@ function get_host_info_from_security_blob(security_blob) local pos = domain_offset + 1 -- +1 to convert to Lua's 1-based indexes local target_realm pos, target_realm = bin.unpack( string.format( "A%d", length ), security_blob, pos ) - ntlm_challenge[ "target_realm" ] = from_unicode( target_realm ) + ntlm_challenge[ "target_realm" ] = unicode.utf16to8( target_realm ) end -- Parse the TargetInfo data (Wireshark calls this the "Address List") @@ -814,7 +794,7 @@ function get_host_info_from_security_blob(security_blob) -- this is a FILETIME value (see [MS-DTYP]), representing the time in 100-ns increments since 1/1/1601 ntlm_challenge[ friendly_name ] = bin.unpack( "= #target_info ) end