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