15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SANDBOX_TOOLS_FINDER_FINDER_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_TOOLS_FINDER_FINDER_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/restricted_token_utils.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/tools/finder/ntundoc.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Type of stats that we calculate during the Scan operation 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum Stats { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) READ = 0, // Number of objects with read access 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WRITE, // Number of objects with write access 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ALL, // Number of objects with r/w access 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PARSE, // Number of objects parsed 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BROKEN, // Number of errors while parsing the objects 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIZE_STATS // size of the enum 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kScanRegistry = 0x01; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kScanFileSystem = 0x02; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kScanKernelObjects = 0x04; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTestForRead = 0x01; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTestForWrite = 0x02; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTestForAll = 0x04; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FS_ERR L"FILE-ERROR" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OBJ_ERR L"OBJ-ERROR" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REG_ERR L"REG_ERROR" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OBJ L"OBJ" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FS L"FILE" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REG L"REG" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The impersonater class will impersonate a token when the object is created 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and revert when the object is going out of scope. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Impersonater { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Impersonater(HANDLE token_handle) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (token_handle) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ImpersonateLoggedOnUser(token_handle); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Impersonater() { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::RevertToSelf(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The finder class handles the search of objects (file system, registry, kernel 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// objects) on the system that can be opened by a restricted token. It can 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// support multiple levels of restriction for the restricted token and can check 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for read, write or r/w access. It outputs the results to a file or stdout. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Finder { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Finder(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Finder(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD Init(sandbox::TokenLevel token_type, DWORD object_type, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD access_type, FILE *file_output); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD Scan(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parses a file system path and perform an access check on all files and 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // folder found. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // win32 error code associated with the error. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ParseFileSystem(ATL::CString path); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parses a registry hive referenced by "key" and performs an access check on 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all subkeys found. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // win32 error code associated with the error. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ParseRegistry(HKEY key, ATL::CString print_name); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parses the kernel namespace beginning at "path" and performs an access 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check on all objects found. However, only some object types are supported, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all non supported objects are ignored. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // win32 error code associated with the error. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ParseKernelObjects(ATL::CString path); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks if "path" can be accessed with the restricted token. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the access granted. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD TestFileAccess(ATL::CString path); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks if the registry key with the path key\name can be accessed with the 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // restricted token. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // print_name is only use for logging purpose. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the access granted. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD TestRegAccess(HKEY key, ATL::CString name, ATL::CString print_name); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks if the kernel object "path" of type "type" can be accessed with 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the restricted token. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the access granted. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD TestKernelObjectAccess(ATL::CString path, ATL::CString type); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Outputs information to the logfile 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Output(ATL::CString type, ATL::CString access, ATL::CString info) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(file_output_, "\n%S;%S;%S", type.GetBuffer(), access.GetBuffer(), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.GetBuffer()); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output information to the log file. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Output(ATL::CString type, DWORD error, ATL::CString info) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(file_output_, "\n%S;0x%X;%S", type.GetBuffer(), error, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.GetBuffer()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set func_to_call to the function pointer of the function used to handle 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests for the kernel objects of type "type". If the type is not 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // supported at the moment the function returns false and the func_to_call 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter is not modified. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetFunctionForType(ATL::CString type, NTGENERICOPEN * func_to_call); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the NT function pointers to be able to use all the needed 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // functions in NTDDL. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // win32 error code associated with the error. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD InitNT(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calls func_to_call with the parameters desired_access, object_attributes 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and handle. func_to_call is a pointer to a function to open a kernel 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NTSTATUS NtGenericOpen(ACCESS_MASK desired_access, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OBJECT_ATTRIBUTES *object_attributes, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NTGENERICOPEN func_to_call, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE *handle); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Type of object to check for. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD object_type_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Access to try. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD access_type_; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output file for the results. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE * file_output_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle to the restricted token. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE token_handle_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stats containing the number of operations performed on the different 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // objects. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int filesystem_stats_[SIZE_STATS]; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int registry_stats_[SIZE_STATS]; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kernel_object_stats_[SIZE_STATS]; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_TOOLS_FINDER_FINDER_H__ 144