Overview of secpod_smb_func.inc

Public Variable Summary

Public variables are intended to be accessed by the code that imports this library.

Name Summary
domain
login
name
pass
port

Public Function Summary

Public functions are intended to be called by the code that imports this library.

Name Summary
GetVer
GetVersion
GetVersionFromFile
bin_dword
bin_word
get_file_size
open_file
read_file
registry_enum_keys
registry_enum_values

Public Variable Details

domain

top

login

top

name

top

pass

top

port

top

Public Function Details

GetVer

Named Parameters

file
prodvers
share

Code

function GetVer(file, share, prodvers)
{
  local_var pe_offset, sections_cnt, sections_offset, sections_data, i, rsrc_start, rsrc_virtstart;
  local_var dir_data, dir_offset, dir_entries, sub_dir, dir_tmp, vs_data, vs_length, reply, recurs, max_recurs, vs_offset;
  local_var itr, it;

  if(isnull(prodvers)){
    prodvers = 0;
  }

  pe_offset = bin_word(data: read_file(share:share, file:file, offset:60, count:2));

  if(read_file(share:share, file:file, offset:pe_offset, count:2) != "PE"){
    return NULL;
  }

  sections_cnt = bin_word(data: read_file(share:share, file:file,
                          offset:pe_offset+6, count:2));
  section_offset = pe_offset + bin_word(data:read_file(share:share, file:file,
                                        offset:pe_offset+20, count:2)) + 24;
  rsrc_start = NULL;
  max_recurs = 20;

  for( itr=0; itr<sections_cnt; itr++ )
  {
    sections_data = read_file(share:share, file:file, offset:section_offset + itr * 40,
                              count:40);
    if(substr(sections_data, 0, 4) == ".rsrc")
    {
      rsrc_start = bin_dword(data:substr(sections_data, 20));
      rsrc_virtstart = bin_dword(data:substr(sections_data, 12));
      break;
    }
    if(itr > max_recurs){
      break;
    }
  }
  if(isnull(rsrc_start)){
    return NULL;
  }

  dir_data = read_file(share:share, file:file, offset:rsrc_start, count:16);
  dir_entries = bin_word(data:substr(dir_data,12)) + bin_word(data:substr(dir_data,14));
  dir_offset = NULL;
  sub_dir = 0;
  max_recurs = 100;
  recurs = 0;
  for(it = 0; it < dir_entries; it++)
  {
    dir_data = read_file(file:file, offset:rsrc_start+16+it*8, count:8);
    if(bin_dword(data:substr(dir_data,0)) == 0x10)
    {
      repeat
      {
        dir_tmp = bin_dword(data:substr(dir_data,4));
        if((dir_tmp & 0x80000000) == 0x80000000)
        {
          dir_offset = dir_tmp - 0x80000000;
          sub_dir = 1;
        }
        else
        {
          dir_offset = dir_tmp;
          sub_dir = 0;
        }
        dir_data = read_file(share:share, file:file, offset:rsrc_start+dir_offset+16,
                             count:8);
        if(strlen(dir_data) != 8){
          return NULL;
        }
        if(++recurs > max_recurs){
          return NULL;
        }
      }
      until sub_dir == 0;
      break;
    }
    if(it > max_recurs){
      break;
    }
  }
  if(isnull(dir_offset)){
    return NULL;
  }

  dir_data = read_file(share:share, file:file, offset:rsrc_start+dir_offset,
                       count:4);
  dir_offset = bin_dword(data:substr(dir_data,0));
  rsrc_start = rsrc_start + (dir_offset - rsrc_virtstart);
  vs_data = read_file(share:share, file:file, offset:rsrc_start, count:2);
  if(!vs_data){
    return NULL;
  }

  vs_length = bin_word(data:substr(vs_data,0));
  vs_data = read_file(share:share, file:file, offset:rsrc_start, count:vs_length);

  if(bin_dword(data:substr(vs_data,40)) != 0xfeef04bd){
    return NULL;
  }

  if(prodvers == 0){
    vs_offset = 48;
  }
  else{
    vs_offset = 56;
  }

  reply = NULL;
  reply = string((bin_dword(data:substr(vs_data, vs_offset)) >>> 16) + ".");
  reply = reply + string((bin_dword(data:substr(vs_data, vs_offset)) & 0xffff) + ".");
  reply = reply + string((bin_dword(data:substr(vs_data, vs_offset+4)) >>> 16) + ".");
  reply = reply + string((bin_dword(data:substr(vs_data, vs_offset+4)) & 0xffff));
  return reply;
}

function bin_word(data)

		
top

GetVersion

Named Parameters

debug
fid
offset
socket
tid
uid
verstr

Code

function GetVersion(socket, uid, tid, fid, offset, verstr, debug)
{

  local_var fsize, data, i, offset, tmp, version, ver, vers, len, retVal;

  pattern = "F?i?l?e?V?e?r?s?i?o?n";
  if(verstr == "prod"){
    pattern = "P?r?o?d?u?c?t?V?e?r?s?i?o?n";
  }

  else if(verstr){
   pattern = verstr;
  }

  patlen = strlen(pattern);

  fsize = smb_get_file_size(socket:socket, uid:uid, tid:tid, fid:fid);

  if(isnull(offset))
  {
    if(fsize < 180224){
      offset = 0;
    }
    else{
      offset = fsize - 180224;
    }
  }

  if(offset < 0){
     offset = fsize + offset;
  }

  start = offset;

  if(start < 0 || start > fsize){
    start = fsize/2;
  }

  offset = start;
  chunk = 16384;

  for(i = 0; offset < fsize; i++)
  {
    tmp = ReadAndX(socket:socket, uid:uid, tid:tid, fid:fid, count:chunk, off:offset);
    if(tmp)
    {
      if(pattern == "build"){
        tmp = str_replace(find:raw_string(0), replace:"", string:tmp);
      }
      else
        tmp = str_replace(find:raw_string(0), replace:"?", string:tmp);

      data += tmp;
      version = strstr(data, pattern);
      if(version)
      {
        len = strlen(version);
        for(i = patlen; i < len; i++)
        {
          if((ord(version[i]) < ord("0") || ord(version[i]) > ord("9")) &&
             (version[i] != "." && version[i] != "," && version[i] != " " &&
              version[i] != "?"))
          {
            if(ver[strlen(ver)-1] == ".")
            {
              vers = split(ver, sep:".", keep:0);
              foreach item (vers){
                retVal += string("." + item);
              }
              retVal -= string(".");
                return(retVal);
            }
            return (ver);
          }
          else if(version[i] == "," || version[i] == "."){
            ver += ".";
          }
          else if(ver && version[i] == "?" && version[i+1] == "?"){
            return (ver);
          }
          else if(version[i] == " "||version[i] == "?"){
          }
          else{
            ver += version[i];
          }
        }
      }
      offset += chunk;
    }
  }
  return NULL;
}


global_var name, login, pass, domain, port;

		
top

GetVersionFromFile

Named Parameters

file
verstr

Code

function GetVersionFromFile(file, verstr) {

  local_var file, share, verstr, mshare, soc, r, prot, uid, tid, ver;

  mshare = ereg_replace(pattern:"([A-Z]):.*", replace:"\1$", string:file);
  file = ereg_replace(pattern:"[A-Z]:(.*)", replace:"\1", string:file);

  soc = open_sock_tcp(port);
  if(!soc){
    return NULL;
  }

  r = smb_session_request(soc:soc, remote:name);
  if(!r)
  {
    close(soc);
    return NULL;
  }

  prot = smb_neg_prot(soc:soc);
  if(!prot)
  {
    close(soc);
    return NULL;
  }

  r = smb_session_setup(soc:soc, login:login, password:pass,
                        domain:domain, prot:prot);
  if(!r)
  {
    close(soc);
    return NULL;
  }

  uid = session_extract_uid(reply:r);
  r = smb_tconx(soc:soc, name:name, uid:uid, share:mshare);

  tid = tconx_extract_tid(reply:r);
  if(!tid)
  {
    close(soc);
    return NULL;
  }
  fid = OpenAndX(socket:soc, uid:uid, tid:tid, file:file);
  if(!fid)
  {
    close(soc);
    return NULL;
  }
  if(isnull(verstr)) {
    ver = GetVersion(socket:soc, uid:uid, tid:tid, fid:fid);
  } else {
    ver = GetVersion(socket:soc, uid:uid, tid:tid, fid:fid,verstr:verstr);
  }
  close(soc);

  return ver;


}


		
top

bin_dword

Named Parameters

data

Code

function bin_dword(data)
{
  if(!data){
    return 0;
  }
  else {
    return(ord(data[0]) + (ord(data[1]) << 8) +
         (ord(data[2]) << 16) + (ord(data[3]) << 24));
  }
}

function GetVersionFromFile(file, verstr) {

		
top

bin_word

Named Parameters

data

Code

function bin_word(data)
{
  if(!data){
    return 0;
  }
  else return(ord(data[0]) + (ord(data[1]) << 8));
}


function bin_dword(data)

		
top

get_file_size

Named Parameters

file
share

Code

function get_file_size(share, file)
{
        if(!port){
                port = 445;
        }

        soc = open_sock_tcp(port);
        if(!soc){
                return FALSE;
        }

        r = smb_session_request(soc:soc, remote:name);
        if(!r){
                close(soc);
                return FALSE;
        }

        prot = smb_neg_prot(soc:soc);
        if(!prot){
                close(soc);
                return FALSE;
        }

        r = smb_session_setup(soc:soc, login:login, password:pass,
                              domain:domain, prot:prot);
        if(!r){
                close(soc);
                return FALSE;
        }

        uid = session_extract_uid(reply:r);
        if(!uid)
        {
                close(soc);
                return FALSE;
        }

        r = smb_tconx(soc:soc, name:name, uid:uid, share:share);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        tid = tconx_extract_tid(reply:r);
        if(!tid){
                close(soc);
                return FALSE;
        }

        fid = OpenAndX(socket:soc, uid:uid, tid:tid, file:file);
        if(!fid){
                close(soc);
                return FALSE;
        }
        fileSize = smb_get_file_size(socket:soc, uid:uid, tid:tid, fid:fid);
        smb_close_request(soc:soc, uid:uid, tid:tid, fid:fid);
        close(soc);

        if(fileSize){
                return fileSize;
        }
}




##########################################################################

		
top

open_file

Named Parameters

file
share

Code

function open_file(share, file)
{
        if(!port){
                port = 445;
        }

        soc = open_sock_tcp(port);
        if(!soc){
                return FALSE;
        }

        r = smb_session_request(soc:soc, remote:name);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        prot = smb_neg_prot(soc:soc);
        if(!prot)
        {
                close(soc);
                return FALSE;
        }

        r = smb_session_setup(soc:soc, login:login, password:pass,
                              domain:domain, prot:prot);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        uid = session_extract_uid(reply:r);
        if(!uid)
        {
                close(soc);
                return FALSE;
        }

        r = smb_tconx(soc:soc, name:name, uid:uid, share:share);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        tid = tconx_extract_tid(reply:r);
        if(!tid)
        {
                close(soc);
                return FALSE;
        }

        r = OpenAndX(socket:soc, uid:uid, tid:tid, file:file);
        if(r)
          smb_close_request(soc:soc, uid:uid, tid:tid, fid:r);

        close(soc);
        return r;
}


##########################################################################

		
top

read_file

Named Parameters

count
file
offset
share

Code

function read_file(share, file, offset, count)
{
        if(!port){
                port = 445;
        }

        soc = open_sock_tcp(port);
        if(!soc){
                return FALSE;
        }

        r = smb_session_request(soc:soc, remote:name);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        prot = smb_neg_prot(soc:soc);
        if(!prot)
        {
                close(soc);
                return FALSE;
        }

        r = smb_session_setup(soc:soc, login:login, password:pass,
                                 domain:domain, prot:prot);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        uid = session_extract_uid(reply:r);
        if(!uid)
        {
                close(soc);
                return FALSE;
        }

        r = smb_tconx(soc:soc, name:name, uid:uid, share:share);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        tid = tconx_extract_tid(reply:r);
        if(!tid)
        {
                close(soc);
                return FALSE;
        }

        fid = OpenAndX(socket:soc, uid:uid, tid:tid, file:file);
        if(!fid)
        {
                close(soc);
                return FALSE;
        }
        content = ReadAndX(socket:soc, uid:uid, tid:tid, fid:fid,
                           count:count, off:offset);
        result = smb_close_request(soc:soc, uid:uid, tid:tid, fid:fid);
        close(soc);
        return content;
}

function GetVer(file, share, prodvers)

		
top

registry_enum_keys

Named Parameters

key

Code

function registry_enum_keys(key)
{
        if(!port){
                port = 445;
        }

        soc = open_sock_tcp(port);
        if(!soc) {
                return FALSE;
        }

        r = smb_session_request(soc:soc, remote:name);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        prot = smb_neg_prot(soc:soc);
        if(!prot)
        {
                close(soc);
                 return FALSE;
        }

        r = smb_session_setup(soc:soc, login:login, password:pass,
                                 domain:domain, prot:prot);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        uid = session_extract_uid(reply:r);
        if(!uid)
        {
                close(soc);
                return FALSE;
        }

        r = smb_tconx(soc:soc, name:name, uid:uid, share:"IPC$");
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        tid = tconx_extract_tid(reply:r);
        if(!tid)
        {
                close(soc);
                 return FALSE;
        }

        r = smbntcreatex(soc:soc, uid:uid, tid:tid, name:"\winreg");
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        pipe = smbntcreatex_extract_pipe(reply:r);
        if(!pipe)
        {
                close(soc);
                return FALSE;
        }

        r = pipe_accessible_registry(soc:soc, uid:uid, tid:tid, pipe:pipe);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        handle = registry_open_hklm(soc:soc, uid:uid, tid:tid, pipe:pipe);
        if(!handle)
        {
                close(soc);
                return FALSE;
        }

        r = registry_get_key(soc:soc, uid:uid, tid:tid, pipe:pipe, key:key,
                             reply:handle);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        list = registry_enum_key(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r);
        close(soc);
        return(list);
}


################################################################################

		
top

registry_enum_values

Named Parameters

key

Code

function registry_enum_values(key)
{
        if(!port){
                port = 445;
        }

        soc = open_sock_tcp(port);
        if(!soc){
                return FALSE;
        }

        r = smb_session_request(soc:soc, remote:name);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        prot = smb_neg_prot(soc:soc);
        if(!prot)
        {
                close(soc);
                return FALSE;
        }

        r = smb_session_setup(soc:soc, login:login, password:pass,
                              domain:domain, prot:prot);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        uid = session_extract_uid(reply:r);
        if(!uid)
        {
                close(soc);
                return FALSE;
        }

        r = smb_tconx(soc:soc, name:name, uid:uid, share:"IPC$");
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        tid = tconx_extract_tid(reply:r);
        if(!tid)
        {
                close(soc);
                return FALSE;
        }

        r = smbntcreatex(soc:soc, uid:uid, tid:tid, name:"\winreg");
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        pipe = smbntcreatex_extract_pipe(reply:r);
        if(!pipe)
        {
                close(soc);
                return FALSE;
        }

        r = pipe_accessible_registry(soc:soc, uid:uid, tid:tid, pipe:pipe);
        if(!r)
        {
                close(soc);
                return FALSE;
        }

        handle = registry_open_hklm(soc:soc, uid:uid, tid:tid, pipe:pipe);
        if(!handle)
        {
                close(soc);
                return FALSE;
        }

        r = registry_get_key(soc:soc, uid:uid, tid:tid, pipe:pipe, key:key,
                             reply:handle);

        if(!r)
        {
                close(soc);
                return FALSE;
        }

        list = registry_enum_value(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r);
        close(soc);
        return(list);
}


##############################################################################

		
top