[Windows] Remove Sandbox Proof-of-concept
This CL removes the old sandbox proof-of-concept. This is never used as an actual test and is only kept around for reference. If it's needed again it can be recovered from git history. Bug: 1270309 Change-Id: I6d481fa128fa03fe4d26fd352225ffcedf882c3c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3281778 Reviewed-by: Will Harris <wfh@chromium.org> Reviewed-by: Bruce Dawson <brucedawson@chromium.org> Commit-Queue: James Forshaw <forshaw@chromium.org> Cr-Commit-Position: refs/heads/main@{#941739}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
eded28bbff
commit
0de7fda233
2
BUILD.gn
2
BUILD.gn
@ -678,8 +678,6 @@ group("gn_all") {
|
||||
"//components/zucchini",
|
||||
"//net:quic_client",
|
||||
"//net:quic_server",
|
||||
"//sandbox/win:pocdll",
|
||||
"//sandbox/win:sandbox_poc",
|
||||
"//sandbox/win:sbox_integration_tests",
|
||||
"//sandbox/win:sbox_unittests",
|
||||
"//sandbox/win:sbox_validation_tests",
|
||||
|
@ -348,47 +348,6 @@ test("sbox_unittests") {
|
||||
]
|
||||
}
|
||||
|
||||
test("sandbox_poc") {
|
||||
sources = [
|
||||
"sandbox_poc/main_ui_window.cc",
|
||||
"sandbox_poc/main_ui_window.h",
|
||||
"sandbox_poc/resource.h",
|
||||
"sandbox_poc/sandbox.cc",
|
||||
"sandbox_poc/sandbox.h",
|
||||
"sandbox_poc/sandbox.rc",
|
||||
]
|
||||
|
||||
configs -= [ "//build/config/win:console" ]
|
||||
configs += [ "//build/config/win:windowed" ]
|
||||
|
||||
libs = [ "comctl32.lib" ]
|
||||
|
||||
deps = [
|
||||
":pocdll",
|
||||
":sandbox",
|
||||
]
|
||||
}
|
||||
|
||||
shared_library("pocdll") {
|
||||
sources = [
|
||||
"sandbox_poc/pocdll/exports.h",
|
||||
"sandbox_poc/pocdll/fs.cc",
|
||||
"sandbox_poc/pocdll/handles.cc",
|
||||
"sandbox_poc/pocdll/invasive.cc",
|
||||
"sandbox_poc/pocdll/network.cc",
|
||||
"sandbox_poc/pocdll/ntundoc.h",
|
||||
"sandbox_poc/pocdll/pocdll.cc",
|
||||
"sandbox_poc/pocdll/processes_and_threads.cc",
|
||||
"sandbox_poc/pocdll/registry.cc",
|
||||
"sandbox_poc/pocdll/spyware.cc",
|
||||
"sandbox_poc/pocdll/utils.h",
|
||||
]
|
||||
|
||||
defines = [ "POCDLL_EXPORTS" ]
|
||||
|
||||
deps = [ "//base" ]
|
||||
}
|
||||
|
||||
# This fuzzer will only work on Windows, add fuzz targets which could run on
|
||||
# Linux to //sandbox/ directly.
|
||||
fuzzer_test("sandbox_policy_rule_fuzzer") {
|
||||
|
@ -1,664 +0,0 @@
|
||||
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sandbox/win/sandbox_poc/main_ui_window.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <CommCtrl.h>
|
||||
#include <commdlg.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/win/atl.h"
|
||||
#include "base/win/sid.h"
|
||||
#include "sandbox/win/sandbox_poc/resource.h"
|
||||
#include "sandbox/win/src/acl.h"
|
||||
#include "sandbox/win/src/sandbox.h"
|
||||
#include "sandbox/win/src/win_utils.h"
|
||||
|
||||
HWND MainUIWindow::list_view_ = NULL;
|
||||
|
||||
const wchar_t MainUIWindow::kDefaultDll_[] = L"\\POCDLL.dll";
|
||||
const wchar_t MainUIWindow::kDefaultEntryPoint_[] = L"Run";
|
||||
const wchar_t MainUIWindow::kDefaultLogFile_[] = L"";
|
||||
|
||||
MainUIWindow::MainUIWindow()
|
||||
: broker_(nullptr),
|
||||
spawn_target_(L""),
|
||||
instance_handle_(NULL),
|
||||
dll_path_(L""),
|
||||
entry_point_(L"") {}
|
||||
|
||||
MainUIWindow::~MainUIWindow() {
|
||||
}
|
||||
|
||||
unsigned int MainUIWindow::CreateMainWindowAndLoop(
|
||||
HINSTANCE instance,
|
||||
wchar_t* command_line,
|
||||
int show_command,
|
||||
sandbox::BrokerServices* broker) {
|
||||
DCHECK(instance);
|
||||
DCHECK(command_line);
|
||||
DCHECK(broker);
|
||||
|
||||
instance_handle_ = instance;
|
||||
spawn_target_ = command_line;
|
||||
broker_ = broker;
|
||||
|
||||
// We'll use spawn_target_ later for creating a child process, but
|
||||
// CreateProcess doesn't like double quotes, so we remove them along with
|
||||
// tabs and spaces from the start and end of the string
|
||||
const wchar_t *trim_removal = L" \r\t\"";
|
||||
spawn_target_.erase(0, spawn_target_.find_first_not_of(trim_removal));
|
||||
spawn_target_.erase(spawn_target_.find_last_not_of(trim_removal) + 1);
|
||||
|
||||
WNDCLASSEX window_class = {0};
|
||||
window_class.cbSize = sizeof(WNDCLASSEX);
|
||||
window_class.style = CS_HREDRAW | CS_VREDRAW;
|
||||
window_class.lpfnWndProc = MainUIWindow::WndProc;
|
||||
window_class.cbClsExtra = 0;
|
||||
window_class.cbWndExtra = 0;
|
||||
window_class.hInstance = instance;
|
||||
window_class.hIcon =
|
||||
::LoadIcon(instance, MAKEINTRESOURCE(IDI_SANDBOX));
|
||||
window_class.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
||||
window_class.hbrBackground = GetStockBrush(WHITE_BRUSH);
|
||||
window_class.lpszMenuName = MAKEINTRESOURCE(IDR_MENU_MAIN_UI);
|
||||
window_class.lpszClassName = L"sandbox_ui_1";
|
||||
window_class.hIconSm = NULL;
|
||||
|
||||
INITCOMMONCONTROLSEX controls = {
|
||||
sizeof(INITCOMMONCONTROLSEX),
|
||||
ICC_STANDARD_CLASSES | ICC_LISTVIEW_CLASSES
|
||||
};
|
||||
::InitCommonControlsEx(&controls);
|
||||
|
||||
if (!::RegisterClassEx(&window_class))
|
||||
return ::GetLastError();
|
||||
|
||||
// Create a main window of size 600x400
|
||||
HWND window = ::CreateWindowW(window_class.lpszClassName,
|
||||
L"", // window name
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, // x
|
||||
CW_USEDEFAULT, // y
|
||||
600, // width
|
||||
400, // height
|
||||
NULL, // parent
|
||||
NULL, // NULL = use class menu
|
||||
instance,
|
||||
0); // lpParam
|
||||
|
||||
if (NULL == window)
|
||||
return ::GetLastError();
|
||||
|
||||
::SetWindowLongPtr(window,
|
||||
GWLP_USERDATA,
|
||||
reinterpret_cast<LONG_PTR>(this));
|
||||
|
||||
::SetWindowText(window, L"Sandbox Proof of Concept");
|
||||
|
||||
::ShowWindow(window, show_command);
|
||||
|
||||
MSG message;
|
||||
// Now lets start the message pump retrieving messages for any window that
|
||||
// belongs to the current thread
|
||||
while (::GetMessage(&message, NULL, 0, 0)) {
|
||||
::TranslateMessage(&message);
|
||||
::DispatchMessage(&message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK MainUIWindow::WndProc(HWND window,
|
||||
UINT message_id,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
MainUIWindow* host = FromWindow(window);
|
||||
|
||||
#define HANDLE_MSG(hwnd, message, fn) \
|
||||
case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))
|
||||
|
||||
switch (message_id) {
|
||||
case WM_CREATE:
|
||||
// 'host' is not yet available when we get the WM_CREATE message
|
||||
return HANDLE_WM_CREATE(window, wparam, lparam, OnCreate);
|
||||
case WM_DESTROY:
|
||||
return HANDLE_WM_DESTROY(window, wparam, lparam, host->OnDestroy);
|
||||
case WM_SIZE:
|
||||
return HANDLE_WM_SIZE(window, wparam, lparam, host->OnSize);
|
||||
case WM_COMMAND: {
|
||||
// Look at which menu item was clicked on (or which accelerator)
|
||||
int id = LOWORD(wparam);
|
||||
switch (id) {
|
||||
case ID_FILE_EXIT:
|
||||
host->OnFileExit();
|
||||
break;
|
||||
case ID_COMMANDS_SPAWNTARGET:
|
||||
host->OnCommandsLaunch(window);
|
||||
break;
|
||||
default:
|
||||
// Some other menu item or accelerator
|
||||
break;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
default:
|
||||
// Some other WM_message, let it pass to DefWndProc
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(window, message_id, wparam, lparam);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK MainUIWindow::SpawnTargetWndProc(HWND dialog,
|
||||
UINT message_id,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
// Grab a reference to the main UI window (from the window handle)
|
||||
MainUIWindow* host = FromWindow(GetParent(dialog));
|
||||
DCHECK(host);
|
||||
|
||||
switch (message_id) {
|
||||
case WM_INITDIALOG: {
|
||||
// Initialize the window text for DLL name edit box
|
||||
HWND edit_box_dll_name = ::GetDlgItem(dialog, IDC_DLL_NAME);
|
||||
wchar_t current_dir[MAX_PATH];
|
||||
if (GetCurrentDirectory(MAX_PATH, current_dir)) {
|
||||
std::wstring dll_path =
|
||||
std::wstring(current_dir) + std::wstring(kDefaultDll_);
|
||||
::SetWindowText(edit_box_dll_name, dll_path.c_str());
|
||||
}
|
||||
|
||||
// Initialize the window text for Entry Point edit box
|
||||
HWND edit_box_entry_point = ::GetDlgItem(dialog, IDC_ENTRY_POINT);
|
||||
::SetWindowText(edit_box_entry_point, kDefaultEntryPoint_);
|
||||
|
||||
// Initialize the window text for Log File edit box
|
||||
HWND edit_box_log_file = ::GetDlgItem(dialog, IDC_LOG_FILE);
|
||||
::SetWindowText(edit_box_log_file, kDefaultLogFile_);
|
||||
|
||||
return static_cast<INT_PTR>(TRUE);
|
||||
}
|
||||
case WM_COMMAND:
|
||||
// If the user presses the OK button (Launch)
|
||||
if (LOWORD(wparam) == IDOK) {
|
||||
if (host->OnLaunchDll(dialog)) {
|
||||
if (host->SpawnTarget()) {
|
||||
::EndDialog(dialog, LOWORD(wparam));
|
||||
}
|
||||
}
|
||||
return static_cast<INT_PTR>(TRUE);
|
||||
} else if (LOWORD(wparam) == IDCANCEL) {
|
||||
// If the user presses the Cancel button
|
||||
::EndDialog(dialog, LOWORD(wparam));
|
||||
return static_cast<INT_PTR>(TRUE);
|
||||
} else if (LOWORD(wparam) == IDC_BROWSE_DLL) {
|
||||
// If the user presses the Browse button to look for a DLL
|
||||
std::wstring dll_path = host->OnShowBrowseForDllDlg(dialog);
|
||||
if (dll_path.length() > 0) {
|
||||
// Initialize the window text for Log File edit box
|
||||
HWND edit_box_dll_path = ::GetDlgItem(dialog, IDC_DLL_NAME);
|
||||
::SetWindowText(edit_box_dll_path, dll_path.c_str());
|
||||
}
|
||||
return static_cast<INT_PTR>(TRUE);
|
||||
} else if (LOWORD(wparam) == IDC_BROWSE_LOG) {
|
||||
// If the user presses the Browse button to look for a log file
|
||||
std::wstring log_path = host->OnShowBrowseForLogFileDlg(dialog);
|
||||
if (log_path.length() > 0) {
|
||||
// Initialize the window text for Log File edit box
|
||||
HWND edit_box_log_file = ::GetDlgItem(dialog, IDC_LOG_FILE);
|
||||
::SetWindowText(edit_box_log_file, log_path.c_str());
|
||||
}
|
||||
return static_cast<INT_PTR>(TRUE);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return static_cast<INT_PTR>(FALSE);
|
||||
}
|
||||
|
||||
MainUIWindow* MainUIWindow::FromWindow(HWND main_window) {
|
||||
// We store a 'this' pointer using SetWindowLong in CreateMainWindowAndLoop
|
||||
// so that we can retrieve it with this function later. This prevents us
|
||||
// from having to define all the message handling functions (that we refer to
|
||||
// in the window proc) as static
|
||||
::GetWindowLongPtr(main_window, GWLP_USERDATA);
|
||||
return reinterpret_cast<MainUIWindow*>(
|
||||
::GetWindowLongPtr(main_window, GWLP_USERDATA));
|
||||
}
|
||||
|
||||
BOOL MainUIWindow::OnCreate(HWND parent_window, LPCREATESTRUCT) {
|
||||
// Create the listview that will the main app UI
|
||||
list_view_ = ::CreateWindow(WC_LISTVIEW, // Class name
|
||||
L"", // Window name
|
||||
WS_CHILD | WS_VISIBLE | LVS_REPORT |
|
||||
LVS_NOCOLUMNHEADER | WS_BORDER,
|
||||
0, // x
|
||||
0, // y
|
||||
0, // width
|
||||
0, // height
|
||||
parent_window, // parent
|
||||
NULL, // menu
|
||||
::GetModuleHandle(NULL),
|
||||
0); // lpParam
|
||||
|
||||
DCHECK(list_view_);
|
||||
if (!list_view_)
|
||||
return FALSE;
|
||||
|
||||
LVCOLUMN list_view_column = {0};
|
||||
list_view_column.mask = LVCF_FMT | LVCF_WIDTH;
|
||||
list_view_column.fmt = LVCFMT_LEFT;
|
||||
list_view_column.cx = 10000; // Maximum size of an entry in the list view.
|
||||
ListView_InsertColumn(list_view_, 0, &list_view_column);
|
||||
|
||||
// Set list view to show green font on black background
|
||||
ListView_SetBkColor(list_view_, CLR_NONE);
|
||||
ListView_SetTextColor(list_view_, RGB(0x0, 0x0, 0x0));
|
||||
ListView_SetTextBkColor(list_view_, CLR_NONE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void MainUIWindow::OnDestroy(HWND window) {
|
||||
// Post a quit message because our application is over when the
|
||||
// user closes this window.
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
|
||||
void MainUIWindow::OnSize(HWND window, UINT state, int cx, int cy) {
|
||||
// If we have a valid inner child, resize it to cover the entire
|
||||
// client area of the main UI window.
|
||||
if (list_view_) {
|
||||
::MoveWindow(list_view_,
|
||||
0, // x
|
||||
0, // y
|
||||
cx, // width
|
||||
cy, // height
|
||||
TRUE); // repaint
|
||||
}
|
||||
}
|
||||
|
||||
void MainUIWindow::OnPaint(HWND window) {
|
||||
PAINTSTRUCT paintstruct;
|
||||
::BeginPaint(window, &paintstruct);
|
||||
// add painting code here if required
|
||||
::EndPaint(window, &paintstruct);
|
||||
}
|
||||
|
||||
void MainUIWindow::OnFileExit() {
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
|
||||
void MainUIWindow::OnCommandsLaunch(HWND window) {
|
||||
// User wants to see the Select DLL dialog box
|
||||
::DialogBox(instance_handle_,
|
||||
MAKEINTRESOURCE(IDD_LAUNCH_DLL),
|
||||
window,
|
||||
SpawnTargetWndProc);
|
||||
}
|
||||
|
||||
bool MainUIWindow::OnLaunchDll(HWND dialog) {
|
||||
HWND edit_box_dll_name = ::GetDlgItem(dialog, IDC_DLL_NAME);
|
||||
HWND edit_box_entry_point = ::GetDlgItem(dialog, IDC_ENTRY_POINT);
|
||||
HWND edit_log_file = ::GetDlgItem(dialog, IDC_LOG_FILE);
|
||||
|
||||
wchar_t dll_path[MAX_PATH];
|
||||
wchar_t entry_point[MAX_PATH];
|
||||
wchar_t log_file[MAX_PATH];
|
||||
|
||||
int dll_name_len = ::GetWindowText(edit_box_dll_name, dll_path, MAX_PATH);
|
||||
int entry_point_len = ::GetWindowText(edit_box_entry_point,
|
||||
entry_point, MAX_PATH);
|
||||
// Log file is optional (can be blank)
|
||||
::GetWindowText(edit_log_file, log_file, MAX_PATH);
|
||||
|
||||
if (0 >= dll_name_len) {
|
||||
::MessageBox(dialog,
|
||||
L"Please specify a DLL for the target to load",
|
||||
L"No DLL specified",
|
||||
MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetFileAttributes(dll_path) == INVALID_FILE_ATTRIBUTES) {
|
||||
::MessageBox(dialog,
|
||||
L"DLL specified was not found",
|
||||
L"DLL not found",
|
||||
MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 >= entry_point_len) {
|
||||
::MessageBox(dialog,
|
||||
L"Please specify an entry point for the DLL",
|
||||
L"No entry point specified",
|
||||
MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// store these values in the member variables for use in SpawnTarget
|
||||
log_file_ = std::wstring(L"\"") + log_file + std::wstring(L"\"");
|
||||
dll_path_ = dll_path;
|
||||
entry_point_ = entry_point;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD WINAPI MainUIWindow::ListenPipeThunk(void *param) {
|
||||
return reinterpret_cast<MainUIWindow*>(param)->ListenPipe();
|
||||
}
|
||||
|
||||
DWORD WINAPI MainUIWindow::WaitForTargetThunk(void *param) {
|
||||
return reinterpret_cast<MainUIWindow*>(param)->WaitForTarget();
|
||||
}
|
||||
|
||||
// Thread waiting for the target application to die. It displays
|
||||
// a message in the list view when it happens.
|
||||
DWORD MainUIWindow::WaitForTarget() {
|
||||
WaitForSingleObject(target_.hProcess, INFINITE);
|
||||
|
||||
DWORD exit_code = 0;
|
||||
if (!GetExitCodeProcess(target_.hProcess, &exit_code)) {
|
||||
exit_code = 0xFFFF; // Default exit code
|
||||
}
|
||||
|
||||
::CloseHandle(target_.hProcess);
|
||||
::CloseHandle(target_.hThread);
|
||||
|
||||
AddDebugMessage(L"Targed exited with return code %d", exit_code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Thread waiting for messages on the log pipe. It displays the messages
|
||||
// in the listview.
|
||||
DWORD MainUIWindow::ListenPipe() {
|
||||
HANDLE logfile_handle = NULL;
|
||||
ATL::CString file_to_open = log_file_.c_str();
|
||||
file_to_open.Remove(L'\"');
|
||||
if (file_to_open.GetLength()) {
|
||||
logfile_handle = ::CreateFile(file_to_open.GetBuffer(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, // Default security attributes
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL); // No template
|
||||
if (INVALID_HANDLE_VALUE == logfile_handle) {
|
||||
AddDebugMessage(L"Failed to open \"%ls\" for logging. Error %d",
|
||||
file_to_open.GetBuffer(), ::GetLastError());
|
||||
logfile_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const int kSizeBuffer = 1024;
|
||||
BYTE read_buffer[kSizeBuffer] = {0};
|
||||
ATL::CStringA read_buffer_global;
|
||||
ATL::CStringA string_to_print;
|
||||
|
||||
DWORD last_error = 0;
|
||||
while (last_error == ERROR_SUCCESS || last_error == ERROR_PIPE_LISTENING ||
|
||||
last_error == ERROR_NO_DATA) {
|
||||
DWORD read_data_length;
|
||||
if (::ReadFile(pipe_handle_,
|
||||
read_buffer,
|
||||
kSizeBuffer - 1, // Max read size
|
||||
&read_data_length,
|
||||
NULL)) { // Not overlapped
|
||||
if (logfile_handle) {
|
||||
DWORD write_data_length;
|
||||
::WriteFile(logfile_handle,
|
||||
read_buffer,
|
||||
read_data_length,
|
||||
&write_data_length,
|
||||
FALSE); // Not overlapped
|
||||
}
|
||||
|
||||
// Append the new buffer to the current buffer
|
||||
read_buffer[read_data_length] = NULL;
|
||||
read_buffer_global += reinterpret_cast<char *>(read_buffer);
|
||||
read_buffer_global.Remove(10); // Remove the CRs
|
||||
|
||||
// If we completed a new line, output it
|
||||
int endline = read_buffer_global.Find(13); // search for LF
|
||||
while (-1 != endline) {
|
||||
string_to_print = read_buffer_global;
|
||||
string_to_print.Delete(endline, string_to_print.GetLength());
|
||||
read_buffer_global.Delete(0, endline);
|
||||
|
||||
// print the line (with the ending LF)
|
||||
OutputDebugStringA(string_to_print.GetBuffer());
|
||||
|
||||
// Remove the ending LF
|
||||
read_buffer_global.Delete(0, 1);
|
||||
|
||||
// Add the line to the log
|
||||
AddDebugMessage(L"%S", string_to_print.GetBuffer());
|
||||
|
||||
endline = read_buffer_global.Find(13);
|
||||
}
|
||||
last_error = ERROR_SUCCESS;
|
||||
} else {
|
||||
last_error = GetLastError();
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
if (read_buffer_global.GetLength()) {
|
||||
AddDebugMessage(L"%S", read_buffer_global.GetBuffer());
|
||||
}
|
||||
|
||||
CloseHandle(pipe_handle_);
|
||||
|
||||
if (logfile_handle) {
|
||||
CloseHandle(logfile_handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MainUIWindow::SpawnTarget() {
|
||||
// Generate the pipe name
|
||||
GUID random_id;
|
||||
CoCreateGuid(&random_id);
|
||||
|
||||
wchar_t log_pipe[MAX_PATH] = {0};
|
||||
wnsprintf(log_pipe, MAX_PATH - 1,
|
||||
L"\\\\.\\pipe\\sbox_pipe_log_%lu_%lu_%lu_%lu",
|
||||
random_id.Data1,
|
||||
random_id.Data2,
|
||||
random_id.Data3,
|
||||
random_id.Data4);
|
||||
|
||||
// We concatenate the four strings, add three spaces and a zero termination
|
||||
// We use the resulting string as a param to CreateProcess (in SpawnTarget)
|
||||
// Documented maximum for command line in CreateProcess is 32K (msdn)
|
||||
size_t size_call = spawn_target_.length() + entry_point_.length() +
|
||||
dll_path_.length() + wcslen(log_pipe) + 6;
|
||||
if (32 * 1024 < (size_call * sizeof(wchar_t))) {
|
||||
AddDebugMessage(L"The length of the arguments exceeded 32K. "
|
||||
L"Aborting operation.");
|
||||
return false;
|
||||
}
|
||||
|
||||
wchar_t * arguments = new wchar_t[size_call];
|
||||
wnsprintf(arguments, static_cast<int>(size_call), L"%ls %ls \"%ls\" %ls",
|
||||
spawn_target_.c_str(), entry_point_.c_str(),
|
||||
dll_path_.c_str(), log_pipe);
|
||||
|
||||
arguments[size_call - 1] = L'\0';
|
||||
|
||||
scoped_refptr<sandbox::TargetPolicy> policy = broker_->CreatePolicy();
|
||||
policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
|
||||
policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
|
||||
sandbox::USER_LOCKDOWN);
|
||||
policy->SetAlternateDesktop(true);
|
||||
policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
|
||||
|
||||
// Set the rule to allow the POC dll to be loaded by the target. Note that
|
||||
// the rule allows 'all access' to the DLL, which could mean that the target
|
||||
// could modify the DLL on disk.
|
||||
policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
|
||||
sandbox::TargetPolicy::FILES_ALLOW_ANY, dll_path_.c_str());
|
||||
|
||||
sandbox::ResultCode warning_result = sandbox::SBOX_ALL_OK;
|
||||
DWORD last_error = ERROR_SUCCESS;
|
||||
sandbox::ResultCode result =
|
||||
broker_->SpawnTarget(spawn_target_.c_str(), arguments, policy,
|
||||
&warning_result, &last_error, &target_);
|
||||
|
||||
policy.reset();
|
||||
|
||||
bool return_value = false;
|
||||
if (sandbox::SBOX_ALL_OK != result) {
|
||||
AddDebugMessage(
|
||||
L"Failed to spawn target %ls w/args (%ls), sandbox error code: %d",
|
||||
spawn_target_.c_str(), arguments, result);
|
||||
return_value = false;
|
||||
} else {
|
||||
DWORD thread_id;
|
||||
::CreateThread(NULL, // Default security attributes
|
||||
NULL, // Default stack size
|
||||
&MainUIWindow::WaitForTargetThunk,
|
||||
this,
|
||||
0, // No flags
|
||||
&thread_id);
|
||||
|
||||
pipe_handle_ = ::CreateNamedPipe(log_pipe,
|
||||
PIPE_ACCESS_INBOUND | WRITE_DAC,
|
||||
PIPE_TYPE_MESSAGE | PIPE_NOWAIT,
|
||||
1, // Number of instances.
|
||||
512, // Out buffer size.
|
||||
512, // In buffer size.
|
||||
NMPWAIT_USE_DEFAULT_WAIT,
|
||||
NULL); // Default security descriptor
|
||||
|
||||
if (INVALID_HANDLE_VALUE == pipe_handle_)
|
||||
AddDebugMessage(L"Failed to create pipe. Error %d", ::GetLastError());
|
||||
|
||||
if (!sandbox::AddKnownSidToObject(pipe_handle_, SE_KERNEL_OBJECT,
|
||||
base::win::WellKnownSid::kWorld,
|
||||
GRANT_ACCESS, FILE_ALL_ACCESS))
|
||||
AddDebugMessage(L"Failed to set security on pipe. Error %d",
|
||||
::GetLastError());
|
||||
|
||||
::CreateThread(NULL, // Default security attributes
|
||||
NULL, // Default stack size
|
||||
&MainUIWindow::ListenPipeThunk,
|
||||
this,
|
||||
0, // No flags
|
||||
&thread_id);
|
||||
|
||||
::ResumeThread(target_.hThread);
|
||||
|
||||
AddDebugMessage(L"Successfully spawned target w/args (%ls)", arguments);
|
||||
return_value = true;
|
||||
}
|
||||
|
||||
delete[] arguments;
|
||||
return return_value;
|
||||
}
|
||||
|
||||
std::wstring MainUIWindow::OnShowBrowseForDllDlg(HWND owner) {
|
||||
wchar_t filename[MAX_PATH];
|
||||
wcscpy_s(filename, MAX_PATH, L"");
|
||||
|
||||
OPENFILENAMEW file_info = {0};
|
||||
file_info.lStructSize = sizeof(file_info);
|
||||
file_info.hwndOwner = owner;
|
||||
file_info.lpstrFile = filename;
|
||||
file_info.nMaxFile = MAX_PATH;
|
||||
file_info.lpstrFilter = L"DLL files (*.dll)\0*.dll\0All files\0*.*\0\0\0";
|
||||
|
||||
file_info.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
||||
|
||||
if (GetOpenFileName(&file_info)) {
|
||||
return file_info.lpstrFile;
|
||||
}
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::wstring MainUIWindow::OnShowBrowseForLogFileDlg(HWND owner) {
|
||||
wchar_t filename[MAX_PATH];
|
||||
wcscpy_s(filename, MAX_PATH, L"");
|
||||
|
||||
OPENFILENAMEW file_info = {0};
|
||||
file_info.lStructSize = sizeof(file_info);
|
||||
file_info.hwndOwner = owner;
|
||||
file_info.lpstrFile = filename;
|
||||
file_info.nMaxFile = MAX_PATH;
|
||||
file_info.lpstrFilter = L"Log file (*.txt)\0*.txt\0All files\0*.*\0\0\0";
|
||||
|
||||
file_info.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
|
||||
|
||||
if (GetSaveFileName(&file_info)) {
|
||||
return file_info.lpstrFile;
|
||||
}
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
void MainUIWindow::AddDebugMessage(const wchar_t* format, ...) {
|
||||
DCHECK(format);
|
||||
if (!format)
|
||||
return;
|
||||
|
||||
const int kMaxDebugBuffSize = 1024;
|
||||
|
||||
va_list arg_list;
|
||||
va_start(arg_list, format);
|
||||
|
||||
wchar_t text[kMaxDebugBuffSize + 1];
|
||||
vswprintf_s(text, kMaxDebugBuffSize, format, arg_list);
|
||||
text[kMaxDebugBuffSize] = L'\0';
|
||||
|
||||
InsertLineInListView(text);
|
||||
va_end(arg_list);
|
||||
}
|
||||
|
||||
|
||||
void MainUIWindow::InsertLineInListView(wchar_t* debug_message) {
|
||||
DCHECK(debug_message);
|
||||
if (!debug_message)
|
||||
return;
|
||||
|
||||
// Prepend the time to the message
|
||||
const int kSizeTime = 100;
|
||||
size_t size_message_with_time = wcslen(debug_message) + kSizeTime;
|
||||
wchar_t * message_time = new wchar_t[size_message_with_time];
|
||||
|
||||
time_t time_temp;
|
||||
time_temp = time(NULL);
|
||||
|
||||
struct tm time = {0};
|
||||
localtime_s(&time, &time_temp);
|
||||
|
||||
wcsftime(message_time, kSizeTime, L"[%H:%M:%S] ", &time);
|
||||
|
||||
wcscat_s(message_time, size_message_with_time, debug_message);
|
||||
|
||||
// We add the debug message to the top of the listview
|
||||
LVITEM item;
|
||||
item.iItem = ListView_GetItemCount(list_view_);
|
||||
item.iSubItem = 0;
|
||||
item.mask = LVIF_TEXT | LVIF_PARAM;
|
||||
item.pszText = message_time;
|
||||
item.lParam = 0;
|
||||
|
||||
ListView_InsertItem(list_view_, &item);
|
||||
|
||||
delete[] message_time;
|
||||
}
|
@ -1,194 +0,0 @@
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SANDBOX_WIN_SANDBOX_POC_MAIN_UI_WINDOW_H_
|
||||
#define SANDBOX_WIN_SANDBOX_POC_MAIN_UI_WINDOW_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sandbox {
|
||||
class BrokerServices;
|
||||
}
|
||||
|
||||
// Header file for the MainUIWindow, a simple window with a menu bar that
|
||||
// can pop up a dialog (accessible through the menu bar), to specify a path and
|
||||
// filename of any DLL to load and choose an entry point of their choice
|
||||
// (note: only entry points with no parameters are expected to work).
|
||||
//
|
||||
// The purpose of this is to be able to spawn an EXE inside a SandBox, have it
|
||||
// load a DLL and call the entry point on it to test how it behaves inside the
|
||||
// sandbox. This is useful for developer debugging and for security testing.
|
||||
//
|
||||
// The MainUIWindow also has a listview that displays debugging information to
|
||||
// the user.
|
||||
//
|
||||
// Sample usage:
|
||||
//
|
||||
// MainUIWindow window;
|
||||
// unsigned int ret = window.CreateMainWindowAndLoop(
|
||||
// handle_to_current_instance,
|
||||
// ::GetCommandLineW(),
|
||||
// show_command,
|
||||
// broker);
|
||||
//
|
||||
// The CreateMainWindowAndLoop() contains a message loop that ends when the
|
||||
// user closes the MainUIWindow.
|
||||
|
||||
// This class encapsulates the Main UI window for the broker application.
|
||||
// It simply shows a menu that gives the user the ability (through a dialog) to
|
||||
// specify a DLL and what entry point to call in the DLL.
|
||||
class MainUIWindow {
|
||||
public:
|
||||
MainUIWindow();
|
||||
|
||||
MainUIWindow(const MainUIWindow&) = delete;
|
||||
MainUIWindow& operator=(const MainUIWindow&) = delete;
|
||||
|
||||
~MainUIWindow();
|
||||
|
||||
// Creates the main window, displays it and starts the message pump. This
|
||||
// call will not return until user closes the main UI window that appears
|
||||
// as a result. Arguments 'instance', 'command_line' and 'show_cmd' can be
|
||||
// passed in directly from winmain. The 'broker' argument is a pointer to a
|
||||
// BrokerService that will launch a new EXE inside the sandbox and load the
|
||||
// DLL of the user's choice.
|
||||
unsigned int CreateMainWindowAndLoop(HINSTANCE instance,
|
||||
wchar_t* command_line,
|
||||
int show_command,
|
||||
sandbox::BrokerServices* broker);
|
||||
|
||||
private:
|
||||
// The default value DLL name to add to the edit box.
|
||||
static const wchar_t kDefaultDll_[];
|
||||
|
||||
// The default value to show in the entry point.
|
||||
static const wchar_t kDefaultEntryPoint_[];
|
||||
|
||||
// The default value to show in the log file.
|
||||
static const wchar_t kDefaultLogFile_[];
|
||||
|
||||
// Handles the messages sent to the main UI window. The return value is the
|
||||
// result of the message processing and depends on the message.
|
||||
static LRESULT CALLBACK WndProc(HWND window,
|
||||
UINT message_id,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam);
|
||||
|
||||
// Handles the messages sent to the SpawnTarget dialog. The return value is
|
||||
// the result of the message processing and depends on the message.
|
||||
static INT_PTR CALLBACK SpawnTargetWndProc(HWND dialog,
|
||||
UINT message_id,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam);
|
||||
|
||||
// Retrieves a pointer to the MainWindow from a value stored along with the
|
||||
// window handle (passed in as hwnd). Return value is a pointer to the
|
||||
// MainUIWindow previously stored with SetWindowLong() during WM_CREATE.
|
||||
static MainUIWindow* FromWindow(HWND main_window);
|
||||
|
||||
// Handles the WM_CREATE message for the main UI window. Returns TRUE on
|
||||
// success.
|
||||
static BOOL OnCreate(HWND parent_window, LPCREATESTRUCT);
|
||||
|
||||
// Handles the WM_DESTROY message for the main UI window.
|
||||
void OnDestroy(HWND window);
|
||||
|
||||
// Handles the WM_SIZE message for the main UI window.
|
||||
void OnSize(HWND window, UINT state, int cx, int cy);
|
||||
|
||||
// Handles the WM_PAINT message for the main UI window.
|
||||
void OnPaint(HWND window);
|
||||
|
||||
// Handles the menu command File \ Exit for the main UI window.
|
||||
void OnFileExit();
|
||||
|
||||
// Handles the menu command Commands \ Launch for the main UI window.
|
||||
void OnCommandsLaunch(HWND window);
|
||||
|
||||
// Handles the Launch button in the SpawnTarget dialog (normally clicked
|
||||
// after selecting DLL and entry point). OnLaunchDll will retrieve the
|
||||
// values entered by the user and store it in the members of the class.
|
||||
// Returns true if user selected a non-zero values for DLL filename
|
||||
// (possibly including path also) and entry point.
|
||||
bool OnLaunchDll(HWND dialog);
|
||||
|
||||
// Spawns a target EXE inside the sandbox (with the help of the
|
||||
// BrokerServices passed in to CreateMainWindowAndLoop), and passes to it
|
||||
// (as command line arguments) the DLL path and the entry point function
|
||||
// name. The EXE is expected to parse the command line and load the DLL.
|
||||
// NOTE: The broker does not know if the target EXE successfully loaded the
|
||||
// DLL, for that you have to rely on the EXE providing a log.
|
||||
// Returns true if the broker reports that it was successful in creating
|
||||
// the target and false if not.
|
||||
bool SpawnTarget();
|
||||
|
||||
// Shows a standard File Open dialog and returns the DLL filename selected or
|
||||
// blank string if the user cancelled (or an error occurred).
|
||||
std::wstring OnShowBrowseForDllDlg(HWND owner);
|
||||
|
||||
// Shows a standard Save As dialog and returns the log filename selected or
|
||||
// blank string if the user cancelled (or an error occurred).
|
||||
std::wstring OnShowBrowseForLogFileDlg(HWND owner);
|
||||
|
||||
// Formats a message using the supplied format string and prints it in the
|
||||
// listview in the main UI window. Passing a NULL param in 'fmt' results in
|
||||
// no action being performed. Maximum message length is 1K.
|
||||
void AddDebugMessage(const wchar_t* format, ...);
|
||||
|
||||
// Assists AddDebugMessage in displaying a message in the ListView. It
|
||||
// simply wraps ListView_InsertItem to insert a debugging message to the
|
||||
// top of the list view. Passing a NULL param in 'fmt' results in no action
|
||||
// being performed.
|
||||
void InsertLineInListView(wchar_t* debug_message);
|
||||
|
||||
// Calls ListenPipe using the class instance received in parameter. This is
|
||||
// used to create new threads executing ListenPipe
|
||||
static DWORD WINAPI ListenPipeThunk(void *param);
|
||||
|
||||
// Calls WaitForTargetThunk using the class instance received in parameter
|
||||
// This is used to create new threads executing WaitForTarget.
|
||||
static DWORD WINAPI WaitForTargetThunk(void *param);
|
||||
|
||||
// Listens on a pipe and output the data received to a file and to the UI.
|
||||
DWORD ListenPipe();
|
||||
|
||||
// Waits for the target to dies and display a message in the UI.
|
||||
DWORD WaitForTarget();
|
||||
|
||||
// The BrokerServices will be used to spawn an EXE in a sandbox and ask
|
||||
// it to load a DLL.
|
||||
sandbox::BrokerServices* broker_;
|
||||
|
||||
// Contains the information about the running target.
|
||||
PROCESS_INFORMATION target_;
|
||||
|
||||
// This is essentially a command line to a target executable that the
|
||||
// broker will spawn and ask to load the DLL.
|
||||
std::wstring spawn_target_;
|
||||
|
||||
// A handle to the current instance of the app. Passed in to this class
|
||||
// through CreateMainWindowAndLoop.
|
||||
HINSTANCE instance_handle_;
|
||||
|
||||
// A path to the DLL that the target should load once it executes.
|
||||
std::wstring dll_path_;
|
||||
|
||||
// The name of the entry point the target should call after it loads the DLL.
|
||||
std::wstring entry_point_;
|
||||
|
||||
// The name of the log file to use.
|
||||
std::wstring log_file_;
|
||||
|
||||
// This is a static handle to the list view that fills up the entire main
|
||||
// UI window. The list view is used to display debugging information to the
|
||||
// user.
|
||||
static HWND list_view_;
|
||||
|
||||
// Pipe used to communicate the logs between the target and the broker.
|
||||
HANDLE pipe_handle_;
|
||||
};
|
||||
|
||||
#endif // SANDBOX_WIN_SANDBOX_POC_MAIN_UI_WINDOW_H_
|
@ -1,89 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SANDBOX_WIN_SANDBOX_POC_POCDLL_EXPORTS_H_
|
||||
#define SANDBOX_WIN_SANDBOX_POC_POCDLL_EXPORTS_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef POCDLL_EXPORTS
|
||||
#define POCDLL_API __declspec(dllexport) __cdecl
|
||||
#else
|
||||
#define POCDLL_API __declspec(dllimport) __cdecl
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
// Tries to open several known system path and outputs
|
||||
// the result.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestFileSystem(HANDLE log);
|
||||
|
||||
// Tries to find all handles open in the process and prints the name of the
|
||||
// resource references by the handle along with the access right.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestGetHandle(HANDLE log);
|
||||
|
||||
// Creates a lot of threads until it cannot create more. The goal of this
|
||||
// function is to determine if it's possible to crash the machine when we
|
||||
// flood the machine with new threads
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestThreadBombing(HANDLE log);
|
||||
|
||||
// Takes all cpu of the machine. For each processor on the machine we assign
|
||||
// a thread. This thread will compute a mathematical expression over and over
|
||||
// to take all cpu.
|
||||
// "log" is the handle of the log file.
|
||||
// Note: here we are using the affinity to find out how many processors are on
|
||||
// the machine and to force a thread to run only on a given processor.
|
||||
void POCDLL_API TestTakeAllCpu(HANDLE log);
|
||||
|
||||
// Creates memory in the heap until it fails 5 times in a row and prints the
|
||||
// amount of memory created. This function is used to find out if it's possible
|
||||
// to take all memory on the machine and crash the system.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestUseAllMemory(HANDLE log);
|
||||
|
||||
// Creates millions of kernel objects. This function is used to find out if it's
|
||||
// possible to crash the system if we create too many kernel objects and if we
|
||||
// hold too many handles. All those kernel objects are unnamed.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestCreateObjects(HANDLE log);
|
||||
|
||||
// Receives a hwnd and tries to close it. This is the callback for EnumWindows.
|
||||
// It will be called for each window(hwnd) on the system.
|
||||
// "log" is the handle of the log file.
|
||||
// Always returns TRUE to tell the system that we want to continue the
|
||||
// enumeration.
|
||||
void POCDLL_API TestCloseHWND(HANDLE log);
|
||||
|
||||
// Tries to listen on the port 88.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestNetworkListen(HANDLE log);
|
||||
|
||||
// Lists all processes on the system and tries to open them
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestProcesses(HANDLE log);
|
||||
|
||||
// Lists all threads on the system and tries to open them
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestThreads(HANDLE log);
|
||||
|
||||
// Tries to open some known system registry key and outputs the result.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestRegistry(HANDLE log);
|
||||
|
||||
// Records all keystrokes typed for 15 seconds and then display them.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestSpyKeys(HANDLE log);
|
||||
|
||||
// Tries to read pixels on the monitor and output if the operation
|
||||
// failes or succeeded.
|
||||
// "log" is the handle of the log file.
|
||||
void POCDLL_API TestSpyScreen(HANDLE log);
|
||||
|
||||
// Runs all tests except those who are invasive
|
||||
void POCDLL_API Run(HANDLE log);
|
||||
}
|
||||
|
||||
#endif // SANDBOX_WIN_SANDBOX_POC_POCDLL_EXPORTS_H_
|
@ -1,54 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
// This file contains the tests used to verify the security of the file system.
|
||||
|
||||
// Tries to open a file and outputs the result.
|
||||
// "path" can contain environment variables.
|
||||
// "output" is the stream for the logging.
|
||||
void TryOpenFile(const wchar_t *path, FILE *output) {
|
||||
wchar_t path_expanded[MAX_PATH] = {0};
|
||||
DWORD size = ::ExpandEnvironmentStrings(path, path_expanded, MAX_PATH - 1);
|
||||
if (!size) {
|
||||
fprintf(output, "[ERROR] Cannot expand \"%S\". Error %ld.\r\n", path,
|
||||
::GetLastError());
|
||||
}
|
||||
|
||||
HANDLE file;
|
||||
file = ::CreateFile(path_expanded,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL, // No security attributes
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL); // No template
|
||||
|
||||
if (file && INVALID_HANDLE_VALUE != file) {
|
||||
fprintf(output, "[GRANTED] Opening file \"%S\". Handle 0x%p\r\n", path,
|
||||
file);
|
||||
::CloseHandle(file);
|
||||
} else {
|
||||
fprintf(output, "[BLOCKED] Opening file \"%S\". Error %ld.\r\n", path,
|
||||
::GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void POCDLL_API TestFileSystem(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
|
||||
TryOpenFile(L"%SystemDrive%", output);
|
||||
TryOpenFile(L"%SystemRoot%", output);
|
||||
TryOpenFile(L"%ProgramFiles%", output);
|
||||
TryOpenFile(L"%SystemRoot%\\System32", output);
|
||||
TryOpenFile(L"%SystemRoot%\\explorer.exe", output);
|
||||
TryOpenFile(L"%SystemRoot%\\Cursors\\arrow_i.cur", output);
|
||||
TryOpenFile(L"%AllUsersProfile%", output);
|
||||
TryOpenFile(L"%UserProfile%", output);
|
||||
TryOpenFile(L"%Temp%", output);
|
||||
TryOpenFile(L"%AppData%", output);
|
||||
}
|
@ -1,186 +0,0 @@
|
||||
// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/ntundoc.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
// This file contains the tests used to verify the security of handles in
|
||||
// the process
|
||||
|
||||
NTQUERYOBJECT NtQueryObject;
|
||||
NTQUERYINFORMATIONFILE NtQueryInformationFile;
|
||||
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
|
||||
|
||||
void POCDLL_API TestGetHandle(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
|
||||
// Initialize the NTAPI functions we need
|
||||
HMODULE ntdll_handle = ::GetModuleHandle(L"ntdll.dll");
|
||||
if (!ntdll_handle) {
|
||||
fprintf(output, "[ERROR] Cannot load ntdll.dll. Error %ld\r\n",
|
||||
::GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
NtQueryObject = reinterpret_cast<NTQUERYOBJECT>(
|
||||
GetProcAddress(ntdll_handle, "NtQueryObject"));
|
||||
NtQueryInformationFile = reinterpret_cast<NTQUERYINFORMATIONFILE>(
|
||||
GetProcAddress(ntdll_handle, "NtQueryInformationFile"));
|
||||
NtQuerySystemInformation = reinterpret_cast<NTQUERYSYSTEMINFORMATION>(
|
||||
GetProcAddress(ntdll_handle, "NtQuerySystemInformation"));
|
||||
|
||||
if (!NtQueryObject || !NtQueryInformationFile || !NtQuerySystemInformation) {
|
||||
fprintf(output, "[ERROR] Cannot load all NT functions. Error %ld\r\n",
|
||||
::GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the number of handles on the system
|
||||
DWORD buffer_size = 0;
|
||||
SYSTEM_HANDLE_INFORMATION_EX temp_info;
|
||||
NTSTATUS status = NtQuerySystemInformation(
|
||||
SystemHandleInformation, &temp_info, sizeof(temp_info),
|
||||
&buffer_size);
|
||||
if (!buffer_size) {
|
||||
fprintf(output, "[ERROR] Get the number of handles. Error 0x%lX\r\n",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
SYSTEM_HANDLE_INFORMATION_EX *system_handles =
|
||||
reinterpret_cast<SYSTEM_HANDLE_INFORMATION_EX*>(new BYTE[buffer_size]);
|
||||
|
||||
status = NtQuerySystemInformation(SystemHandleInformation, system_handles,
|
||||
buffer_size, &buffer_size);
|
||||
if (STATUS_SUCCESS != status) {
|
||||
fprintf(output, "[ERROR] Failed to get the handle list. Error 0x%lX\r\n",
|
||||
status);
|
||||
delete [] system_handles;
|
||||
return;
|
||||
}
|
||||
|
||||
for (ULONG i = 0; i < system_handles->NumberOfHandles; ++i) {
|
||||
USHORT h = system_handles->Information[i].Handle;
|
||||
if (system_handles->Information[i].ProcessId != ::GetCurrentProcessId())
|
||||
continue;
|
||||
|
||||
OBJECT_NAME_INFORMATION *name = NULL;
|
||||
ULONG name_size = 0;
|
||||
// Query the name information a first time to get the size of the name.
|
||||
status = NtQueryObject(reinterpret_cast<HANDLE>(h),
|
||||
ObjectNameInformation,
|
||||
name,
|
||||
name_size,
|
||||
&name_size);
|
||||
|
||||
if (name_size) {
|
||||
name = reinterpret_cast<OBJECT_NAME_INFORMATION *>(new BYTE[name_size]);
|
||||
|
||||
// Query the name information a second time to get the name of the
|
||||
// object referenced by the handle.
|
||||
status = NtQueryObject(reinterpret_cast<HANDLE>(h),
|
||||
ObjectNameInformation,
|
||||
name,
|
||||
name_size,
|
||||
&name_size);
|
||||
}
|
||||
|
||||
PUBLIC_OBJECT_TYPE_INFORMATION *type = NULL;
|
||||
ULONG type_size = 0;
|
||||
|
||||
// Query the object to get the size of the object type name.
|
||||
status = NtQueryObject(reinterpret_cast<HANDLE>(h),
|
||||
ObjectTypeInformation,
|
||||
type,
|
||||
type_size,
|
||||
&type_size);
|
||||
if (type_size) {
|
||||
type = reinterpret_cast<PUBLIC_OBJECT_TYPE_INFORMATION *>(
|
||||
new BYTE[type_size]);
|
||||
|
||||
// Query the type information a second time to get the object type
|
||||
// name.
|
||||
status = NtQueryObject(reinterpret_cast<HANDLE>(h),
|
||||
ObjectTypeInformation,
|
||||
type,
|
||||
type_size,
|
||||
&type_size);
|
||||
}
|
||||
|
||||
// NtQueryObject cannot return the name for a file. In this case we
|
||||
// need to ask NtQueryInformationFile
|
||||
FILE_NAME_INFORMATION *file_name = NULL;
|
||||
if (type && wcsncmp(L"File", type->TypeName.Buffer,
|
||||
(type->TypeName.Length /
|
||||
sizeof(type->TypeName.Buffer[0]))) == 0) {
|
||||
// This function does not return the size of the buffer. We need to
|
||||
// iterate and always increase the buffer size until the function
|
||||
// succeeds. (Or at least does not fail with STATUS_BUFFER_OVERFLOW)
|
||||
ULONG size_file = MAX_PATH;
|
||||
IO_STATUS_BLOCK status_block = {};
|
||||
do {
|
||||
// Delete the previous buffer create. The buffer was too small
|
||||
if (file_name) {
|
||||
delete[] reinterpret_cast<BYTE*>(file_name);
|
||||
file_name = NULL;
|
||||
}
|
||||
|
||||
// Increase the buffer and do the call agan
|
||||
size_file += MAX_PATH;
|
||||
file_name = reinterpret_cast<FILE_NAME_INFORMATION *>(
|
||||
new BYTE[size_file]);
|
||||
status = NtQueryInformationFile(reinterpret_cast<HANDLE>(h),
|
||||
&status_block,
|
||||
file_name,
|
||||
size_file,
|
||||
FileNameInformation);
|
||||
} while (status == STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
if (STATUS_SUCCESS != status) {
|
||||
if (file_name) {
|
||||
delete[] file_name;
|
||||
file_name = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file_name) {
|
||||
UNICODE_STRING file_name_string;
|
||||
file_name_string.Buffer = file_name->FileName;
|
||||
file_name_string.Length = (USHORT)file_name->FileNameLength;
|
||||
file_name_string.MaximumLength = (USHORT)file_name->FileNameLength;
|
||||
fprintf(output, "[GRANTED] Handle 0x%4.4X Access: 0x%8.8lX "
|
||||
"Type: %-13wZ Path: %wZ\r\n",
|
||||
h,
|
||||
system_handles->Information[i].GrantedAccess,
|
||||
type ? &type->TypeName : NULL,
|
||||
&file_name_string);
|
||||
} else {
|
||||
fprintf(output, "[GRANTED] Handle 0x%4.4X Access: 0x%8.8lX "
|
||||
"Type: %-13wZ Path: %wZ\r\n",
|
||||
h,
|
||||
system_handles->Information[i].GrantedAccess,
|
||||
type ? &type->TypeName : NULL,
|
||||
name ? &name->ObjectName : NULL);
|
||||
}
|
||||
|
||||
if (type) {
|
||||
delete[] type;
|
||||
}
|
||||
|
||||
if (file_name) {
|
||||
delete[] file_name;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
delete [] name;
|
||||
}
|
||||
}
|
||||
|
||||
if (system_handles) {
|
||||
delete [] system_handles;
|
||||
}
|
||||
}
|
@ -1,194 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <malloc.h>
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
// This file contains the tests used to verify if it's possible to DOS or crash
|
||||
// the machine. All tests that can impact the stability of the machine should
|
||||
// be in this file.
|
||||
|
||||
// Sleeps forever. this function is used to be the
|
||||
// entry point for the threads created by the thread bombing function.
|
||||
// This function never returns.
|
||||
DWORD WINAPI MyThreadBombimgFunction(void* param) {
|
||||
Sleep(INFINITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void POCDLL_API TestThreadBombing(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE* output = handle2file.Translate(log, "w");
|
||||
|
||||
// we stop after 5 errors in a row
|
||||
int number_errors = 0;
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
DWORD tid;
|
||||
// Create the thread and leak the handle.
|
||||
HANDLE thread = ::CreateThread(NULL, // Default security attributes
|
||||
NULL, // Stack size
|
||||
MyThreadBombimgFunction,
|
||||
NULL, // Parameter
|
||||
0, // No creation flags
|
||||
&tid);
|
||||
if (thread) {
|
||||
fprintf(output, "[GRANTED] Creating thread with tid 0x%lX\r\n", tid);
|
||||
::CloseHandle(thread);
|
||||
number_errors = 0;
|
||||
} else {
|
||||
fprintf(output, "[BLOCKED] Creating thread. Error %ld\r\n",
|
||||
::GetLastError());
|
||||
number_errors++;
|
||||
}
|
||||
|
||||
if (number_errors >= 5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Executes a complex mathematical operation forever in a loop. This function
|
||||
// is used as entry point for the threads created by TestTakeAllCpu. It it
|
||||
// designed to take all CPU on the processor where the thread is running.
|
||||
// The return value is always 0.
|
||||
DWORD WINAPI TakeAllCpu(void* param) {
|
||||
int cpt = 0;
|
||||
for (;;) {
|
||||
cpt += 2;
|
||||
cpt /= 2;
|
||||
cpt *= cpt;
|
||||
cpt = cpt % 100;
|
||||
cpt = cpt | (cpt * cpt);
|
||||
}
|
||||
}
|
||||
|
||||
void POCDLL_API TestTakeAllCpu(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE* output = handle2file.Translate(log, "w");
|
||||
|
||||
DWORD_PTR process_mask = 0;
|
||||
DWORD_PTR system_mask = 0;
|
||||
if (::GetProcessAffinityMask(::GetCurrentProcess(),
|
||||
&process_mask,
|
||||
&system_mask)) {
|
||||
DWORD_PTR affinity_mask = 1;
|
||||
|
||||
while (system_mask) {
|
||||
DWORD tid = 0;
|
||||
|
||||
HANDLE thread = ::CreateThread(NULL, // Default security attributes.
|
||||
NULL, // Stack size.
|
||||
TakeAllCpu,
|
||||
NULL, // Parameter.
|
||||
0, // No creation flags.
|
||||
&tid);
|
||||
::SetThreadAffinityMask(thread, affinity_mask);
|
||||
|
||||
if (::SetThreadPriority(thread, REALTIME_PRIORITY_CLASS)) {
|
||||
fprintf(output, "[GRANTED] Set thread(%ld) priority to Realtime\r\n",
|
||||
tid);
|
||||
} else {
|
||||
fprintf(output, "[BLOCKED] Set thread(%ld) priority to Realtime\r\n",
|
||||
tid);
|
||||
}
|
||||
|
||||
::CloseHandle(thread);
|
||||
|
||||
affinity_mask = affinity_mask << 1;
|
||||
system_mask = system_mask >> 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(output, "[ERROR] Cannot get affinity mask. Error %ld\r\n",
|
||||
::GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void POCDLL_API TestUseAllMemory(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE* output = handle2file.Translate(log, "w");
|
||||
|
||||
int number_errors = 0;
|
||||
unsigned long memory_size = 0;
|
||||
for (;;) {
|
||||
DWORD* ptr_to_leak = reinterpret_cast<DWORD*>(malloc(1024 * 256));
|
||||
if (ptr_to_leak) {
|
||||
memory_size += 256;
|
||||
number_errors = 0;
|
||||
} else {
|
||||
number_errors++;
|
||||
}
|
||||
|
||||
// check if we have more than 5 errors in a row. If so, quit.
|
||||
if (number_errors >= 5) {
|
||||
fprintf(output, "[INFO] Created %lu kb of memory\r\n", memory_size);
|
||||
return;
|
||||
}
|
||||
|
||||
Sleep(5); // 5ms to be able to see the progression easily with taskmgr.
|
||||
}
|
||||
}
|
||||
|
||||
void POCDLL_API TestCreateObjects(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE* output = handle2file.Translate(log, "w");
|
||||
|
||||
int mutexes = 0;
|
||||
int jobs = 0;
|
||||
int events = 0;
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
if (::CreateMutex(NULL, // Default security attributes.
|
||||
TRUE, // We are the initial owner.
|
||||
NULL)) { // No name.
|
||||
mutexes++;
|
||||
}
|
||||
|
||||
if (::CreateJobObject(NULL, // Default security attributes.
|
||||
NULL)) { // No name.
|
||||
jobs++;
|
||||
}
|
||||
|
||||
if (::CreateEvent(NULL, // Default security attributes.
|
||||
TRUE, // Manual Reset.
|
||||
TRUE, // Object is signaled.
|
||||
NULL)) { // No name.
|
||||
events++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output, "[GRANTED] Created %d mutexes, %d jobs and %d events for "
|
||||
"a total of %d objects out of 3 000 000\r\n", mutexes, jobs,
|
||||
events, mutexes + jobs + events);
|
||||
}
|
||||
|
||||
BOOL CALLBACK EnumWindowCallback(HWND hwnd, LPARAM output) {
|
||||
DWORD pid;
|
||||
::GetWindowThreadProcessId(hwnd, &pid);
|
||||
if (pid != ::GetCurrentProcessId()) {
|
||||
wchar_t window_title[100 + 1] = {0};
|
||||
::GetWindowText(hwnd, window_title, 100);
|
||||
fprintf(reinterpret_cast<FILE*>(output),
|
||||
"[GRANTED] Found window 0x%p with title %S\r\n",
|
||||
hwnd,
|
||||
window_title);
|
||||
::CloseWindow(hwnd);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Enumerates all the windows on the system and call the function to try to
|
||||
// close them. The goal of this function is to try to kill the system by
|
||||
// closing all windows.
|
||||
// "output" is the stream used for logging.
|
||||
void POCDLL_API TestCloseHWND(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE* output = handle2file.Translate(log, "w");
|
||||
|
||||
::EnumWindows(EnumWindowCallback, PtrToLong(output));
|
||||
// TODO(nsylvain): find a way to know when the enum is finished
|
||||
// before returning.
|
||||
::Sleep(3000);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
// This file contains the tests used to verify the security of the network.
|
||||
|
||||
void POCDLL_API TestNetworkListen(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
#if DONT_WANT_INTERCEPTIONS_JUST_WANT_NETWORK
|
||||
// Initialize Winsock
|
||||
WSADATA wsa_data;
|
||||
int result = ::WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
||||
if (result != NO_ERROR) {
|
||||
fprintf(output, "[ERROR] Cannot initialize winsock. Error%d\r\n", result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a SOCKET for listening for
|
||||
// incoming connection requests.
|
||||
SOCKET listen_socket;
|
||||
listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (listen_socket == INVALID_SOCKET) {
|
||||
fprintf(output, "[ERROR] Failed to create socket. Error %ld\r\n",
|
||||
::WSAGetLastError());
|
||||
::WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// The sockaddr_in structure specifies the address family,
|
||||
// IP address, and port for the socket that is being bound.
|
||||
sockaddr_in service;
|
||||
service.sin_family = AF_INET;
|
||||
service.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
service.sin_port = htons(88);
|
||||
|
||||
if (bind(listen_socket, reinterpret_cast<SOCKADDR*>(&service),
|
||||
sizeof(service)) == SOCKET_ERROR) {
|
||||
fprintf(output, "[BLOCKED] Bind socket on port 88. Error %ld\r\n",
|
||||
::WSAGetLastError());
|
||||
closesocket(listen_socket);
|
||||
::WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen for incoming connection requests
|
||||
// on the created socket
|
||||
if (listen(listen_socket, SOMAXCONN) == SOCKET_ERROR) {
|
||||
fprintf(output, "[BLOCKED] Listen socket on port 88. Error %ld\r\n",
|
||||
::WSAGetLastError());
|
||||
|
||||
} else {
|
||||
fprintf(output, "[GRANTED] Listen socket on port 88.\r\n",
|
||||
::WSAGetLastError());
|
||||
}
|
||||
|
||||
::WSACleanup();
|
||||
return;
|
||||
#else // DONT_WANT_INTERCEPTIONS_JUST_WANT_NETWORK
|
||||
// Just print out that this test is not running.
|
||||
fprintf(output, "[ERROR] No network tests.\r\n");
|
||||
#endif // DONT_WANT_INTERCEPTIONS_JUST_WANT_NETWORK
|
||||
}
|
@ -1,275 +0,0 @@
|
||||
// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SANDBOX_WIN_SANDBOX_POC_POCDLL_NTUNDOC_H_
|
||||
#define SANDBOX_WIN_SANDBOX_POC_POCDLL_NTUNDOC_H_
|
||||
|
||||
#define NTSTATUS ULONG
|
||||
#define STATUS_SUCCESS 0x00000000
|
||||
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
|
||||
#define STATUS_ACCESS_DENIED 0xC0000022
|
||||
#define STATUS_BUFFER_OVERFLOW 0x80000005
|
||||
|
||||
typedef struct _LSA_UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING;
|
||||
|
||||
typedef struct _OBJDIR_INFORMATION {
|
||||
UNICODE_STRING ObjectName;
|
||||
UNICODE_STRING ObjectTypeName;
|
||||
BYTE Data[1];
|
||||
} OBJDIR_INFORMATION;
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
UNICODE_STRING *ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} OBJECT_ATTRIBUTES;
|
||||
|
||||
typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
|
||||
ULONG Attributes;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
ULONG HandleCount;
|
||||
ULONG PointerCount;
|
||||
ULONG Reserved[10]; // reserved for internal use
|
||||
} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
|
||||
|
||||
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
|
||||
UNICODE_STRING TypeName;
|
||||
ULONG Reserved [22]; // reserved for internal use
|
||||
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
|
||||
|
||||
typedef enum _POOL_TYPE {
|
||||
NonPagedPool,
|
||||
PagedPool,
|
||||
NonPagedPoolMustSucceed,
|
||||
ReservedType,
|
||||
NonPagedPoolCacheAligned,
|
||||
PagedPoolCacheAligned,
|
||||
NonPagedPoolCacheAlignedMustS
|
||||
} POOL_TYPE;
|
||||
|
||||
typedef struct _OBJECT_TYPE_INFORMATION {
|
||||
UNICODE_STRING Name;
|
||||
ULONG TotalNumberOfObjects;
|
||||
ULONG TotalNumberOfHandles;
|
||||
ULONG TotalPagedPoolUsage;
|
||||
ULONG TotalNonPagedPoolUsage;
|
||||
ULONG TotalNamePoolUsage;
|
||||
ULONG TotalHandleTableUsage;
|
||||
ULONG HighWaterNumberOfObjects;
|
||||
ULONG HighWaterNumberOfHandles;
|
||||
ULONG HighWaterPagedPoolUsage;
|
||||
ULONG HighWaterNonPagedPoolUsage;
|
||||
ULONG HighWaterNamePoolUsage;
|
||||
ULONG HighWaterHandleTableUsage;
|
||||
ULONG InvalidAttributes;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
ULONG ValidAccess;
|
||||
BOOLEAN SecurityRequired;
|
||||
BOOLEAN MaintainHandleCount;
|
||||
USHORT MaintainTypeList;
|
||||
POOL_TYPE PoolType;
|
||||
ULONG PagedPoolUsage;
|
||||
ULONG NonPagedPoolUsage;
|
||||
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
|
||||
|
||||
typedef struct _OBJECT_NAME_INFORMATION {
|
||||
UNICODE_STRING ObjectName;
|
||||
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
|
||||
|
||||
typedef enum _OBJECT_INFORMATION_CLASS {
|
||||
ObjectBasicInformation,
|
||||
ObjectNameInformation,
|
||||
ObjectTypeInformation,
|
||||
ObjectAllInformation,
|
||||
ObjectDataInformation
|
||||
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _FILE_NAME_INFORMATION {
|
||||
ULONG FileNameLength;
|
||||
WCHAR FileName[1];
|
||||
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
|
||||
|
||||
typedef enum _FILE_INFORMATION_CLASS {
|
||||
// end_wdm
|
||||
FileDirectoryInformation = 1,
|
||||
FileFullDirectoryInformation, // 2
|
||||
FileBothDirectoryInformation, // 3
|
||||
FileBasicInformation, // 4 wdm
|
||||
FileStandardInformation, // 5 wdm
|
||||
FileInternalInformation, // 6
|
||||
FileEaInformation, // 7
|
||||
FileAccessInformation, // 8
|
||||
FileNameInformation, // 9
|
||||
FileRenameInformation, // 10
|
||||
FileLinkInformation, // 11
|
||||
FileNamesInformation, // 12
|
||||
FileDispositionInformation, // 13
|
||||
FilePositionInformation, // 14 wdm
|
||||
FileFullEaInformation, // 15
|
||||
FileModeInformation, // 16
|
||||
FileAlignmentInformation, // 17
|
||||
FileAllInformation, // 18
|
||||
FileAllocationInformation, // 19
|
||||
FileEndOfFileInformation, // 20 wdm
|
||||
FileAlternateNameInformation, // 21
|
||||
FileStreamInformation, // 22
|
||||
FilePipeInformation, // 23
|
||||
FilePipeLocalInformation, // 24
|
||||
FilePipeRemoteInformation, // 25
|
||||
FileMailslotQueryInformation, // 26
|
||||
FileMailslotSetInformation, // 27
|
||||
FileCompressionInformation, // 28
|
||||
FileObjectIdInformation, // 29
|
||||
FileCompletionInformation, // 30
|
||||
FileMoveClusterInformation, // 31
|
||||
FileQuotaInformation, // 32
|
||||
FileReparsePointInformation, // 33
|
||||
FileNetworkOpenInformation, // 34
|
||||
FileAttributeTagInformation, // 35
|
||||
FileTrackingInformation, // 36
|
||||
FileMaximumInformation
|
||||
// begin_wdm
|
||||
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemHandleInformation = 16
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
NTSTATUS Status;
|
||||
PVOID Pointer;
|
||||
};
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
|
||||
#define InitializeObjectAttributes( p, n, a, r, s ) { \
|
||||
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
|
||||
typedef struct _SYSTEM_HANDLE_INFORMATION {
|
||||
USHORT ProcessId;
|
||||
USHORT CreatorBackTraceIndex;
|
||||
UCHAR ObjectTypeNumber;
|
||||
UCHAR Flags;
|
||||
USHORT Handle;
|
||||
PVOID Object;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
|
||||
ULONG NumberOfHandles;
|
||||
SYSTEM_HANDLE_INFORMATION Information[1];
|
||||
} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
|
||||
|
||||
#define POBJECT_ATTRIBUTES OBJECT_ATTRIBUTES*
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTQUERYDIRECTORYOBJECT)(
|
||||
HANDLE,
|
||||
OBJDIR_INFORMATION*,
|
||||
DWORD,
|
||||
DWORD,
|
||||
DWORD,
|
||||
DWORD*,
|
||||
DWORD*);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENDIRECTORYOBJECT)(
|
||||
HANDLE *,
|
||||
DWORD,
|
||||
OBJECT_ATTRIBUTES* );
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTGENERICOPEN) (
|
||||
OUT PHANDLE EventHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENEVENT)(
|
||||
OUT PHANDLE EventHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENJOBOBJECT)(
|
||||
OUT PHANDLE JobHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENKEYEDEVENT)(
|
||||
OUT PHANDLE KeyedEventHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENMUTANT)(
|
||||
OUT PHANDLE MutantHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENSECTION)(
|
||||
OUT PHANDLE SectionHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENSEMAPHORE)(
|
||||
OUT PHANDLE SemaphoreHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENSYMBOLICLINKOBJECT)(
|
||||
OUT PHANDLE SymbolicLinkHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENTIMER)(
|
||||
OUT PHANDLE TimerHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTOPENFILE)(
|
||||
HANDLE *,
|
||||
DWORD,
|
||||
OBJECT_ATTRIBUTES *,
|
||||
IO_STATUS_BLOCK *,
|
||||
DWORD,
|
||||
DWORD);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTQUERYINFORMATIONFILE)(
|
||||
HANDLE,
|
||||
PIO_STATUS_BLOCK,
|
||||
PVOID,
|
||||
ULONG,
|
||||
FILE_INFORMATION_CLASS);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTQUERYSYSTEMINFORMATION)(
|
||||
SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
PVOID SystemInformation,
|
||||
ULONG SystemInformationLength,
|
||||
PULONG ReturnLength);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTQUERYOBJECT)(
|
||||
HANDLE Handle,
|
||||
OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||
PVOID ObjectInformation,
|
||||
ULONG ObjectInformationLength,
|
||||
PULONG ReturnLength);
|
||||
|
||||
typedef NTSTATUS (WINAPI* NTCLOSE) (HANDLE);
|
||||
|
||||
#define DIRECTORY_QUERY 0x0001
|
||||
#define DIRECTORY_TRAVERSE 0x0002
|
||||
#define DIRECTORY_CREATE_OBJECT 0x0004
|
||||
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
|
||||
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
|
||||
|
||||
#endif // SANDBOX_WIN_SANDBOX_POC_POCDLL_NTUNDOC_H_
|
@ -1,22 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void POCDLL_API Run(HANDLE log) {
|
||||
TestFileSystem(log);
|
||||
TestRegistry(log);
|
||||
TestNetworkListen(log);
|
||||
TestSpyScreen(log);
|
||||
TestSpyKeys(log);
|
||||
TestThreads(log);
|
||||
TestProcesses(log);
|
||||
TestGetHandle(log);
|
||||
}
|
@ -1,218 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="pocdll"
|
||||
ProjectGUID="{AE5BFB87-850E-4454-B01D-58E7D8BAC224}"
|
||||
RootNamespace="pocdll"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;$(SolutionDir)..\build\common.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="POCDLL_EXPORTS"
|
||||
UsePrecompiledHeader="2"
|
||||
ForcedIncludeFiles="stdafx.h"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
ModuleDefinitionFile=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;$(SolutionDir)..\build\common.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="POCDLL_EXPORTS"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
ModuleDefinitionFile=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\exports.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fs.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\handles.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\invasive.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\network.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pocdll.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\processes_and_threads.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\registry.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\spyware.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utils.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,102 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <windows.h>
|
||||
#include <Tlhelp32.h>
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
// This file contains the tests used to verify the security of threads and
|
||||
// processes.
|
||||
|
||||
void POCDLL_API TestProcesses(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
|
||||
HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (INVALID_HANDLE_VALUE == snapshot) {
|
||||
fprintf(output, "[BLOCKED] Cannot list all processes on the system. "
|
||||
"Error %ld\r\n", ::GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
PROCESSENTRY32 process_entry = {0};
|
||||
process_entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
BOOL result = ::Process32First(snapshot, &process_entry);
|
||||
|
||||
while (result) {
|
||||
HANDLE process = ::OpenProcess(PROCESS_VM_READ,
|
||||
FALSE, // Do not inherit handle.
|
||||
process_entry.th32ProcessID);
|
||||
if (NULL == process) {
|
||||
fprintf(output, "[BLOCKED] Found process %S:%ld but cannot open it. "
|
||||
"Error %ld\r\n",
|
||||
process_entry.szExeFile,
|
||||
process_entry.th32ProcessID,
|
||||
::GetLastError());
|
||||
} else {
|
||||
fprintf(output, "[GRANTED] Found process %S:%ld and open succeeded.\r\n",
|
||||
process_entry.szExeFile, process_entry.th32ProcessID);
|
||||
::CloseHandle(process);
|
||||
}
|
||||
|
||||
result = ::Process32Next(snapshot, &process_entry);
|
||||
}
|
||||
|
||||
DWORD err_code = ::GetLastError();
|
||||
if (ERROR_NO_MORE_FILES != err_code) {
|
||||
fprintf(output, "[ERROR] Error %ld while looking at the processes on "
|
||||
"the system\r\n", err_code);
|
||||
}
|
||||
|
||||
::CloseHandle(snapshot);
|
||||
}
|
||||
|
||||
void POCDLL_API TestThreads(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
|
||||
HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);
|
||||
if (INVALID_HANDLE_VALUE == snapshot) {
|
||||
fprintf(output, "[BLOCKED] Cannot list all threads on the system. "
|
||||
"Error %ld\r\n", ::GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
THREADENTRY32 thread_entry = {0};
|
||||
thread_entry.dwSize = sizeof(THREADENTRY32);
|
||||
|
||||
BOOL result = ::Thread32First(snapshot, &thread_entry);
|
||||
int nb_success = 0;
|
||||
int nb_failure = 0;
|
||||
|
||||
while (result) {
|
||||
HANDLE thread = ::OpenThread(THREAD_QUERY_INFORMATION,
|
||||
FALSE, // Do not inherit handles.
|
||||
thread_entry.th32ThreadID);
|
||||
if (NULL == thread) {
|
||||
nb_failure++;
|
||||
} else {
|
||||
nb_success++;
|
||||
fprintf(output, "[GRANTED] Found thread %ld:%ld and able to open it.\r\n",
|
||||
thread_entry.th32OwnerProcessID,
|
||||
thread_entry.th32ThreadID);
|
||||
::CloseHandle(thread);
|
||||
}
|
||||
|
||||
result = Thread32Next(snapshot, &thread_entry);
|
||||
}
|
||||
|
||||
DWORD err_code = ::GetLastError();
|
||||
if (ERROR_NO_MORE_FILES != err_code) {
|
||||
fprintf(output, "[ERROR] Error %ld while looking at the processes on "
|
||||
"the system\r\n", err_code);
|
||||
}
|
||||
|
||||
fprintf(output, "[INFO] Found %d threads. Able to open %d of them\r\n",
|
||||
nb_success + nb_failure, nb_success);
|
||||
|
||||
::CloseHandle(snapshot);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
// This file contains the tests used to verify the security of the registry.
|
||||
|
||||
// Tries to open the key hive\path and outputs the result.
|
||||
// "output" is the stream used for logging.
|
||||
void TryOpenKey(const HKEY hive,
|
||||
const wchar_t* hive_name,
|
||||
const wchar_t* path,
|
||||
FILE* output) {
|
||||
HKEY key;
|
||||
LONG err_code = ::RegOpenKeyEx(hive,
|
||||
path,
|
||||
0, // Reserved, must be 0.
|
||||
MAXIMUM_ALLOWED,
|
||||
&key);
|
||||
if (ERROR_SUCCESS == err_code) {
|
||||
fprintf(output,
|
||||
"[GRANTED] Opening key \"%S\\%S\". Handle 0x%p\r\n",
|
||||
hive_name,
|
||||
path,
|
||||
key);
|
||||
::RegCloseKey(key);
|
||||
} else {
|
||||
fprintf(output,
|
||||
"[BLOCKED] Opening key \"%S\\%S\". Error %ld\r\n",
|
||||
hive_name,
|
||||
path,
|
||||
err_code);
|
||||
}
|
||||
}
|
||||
|
||||
void POCDLL_API TestRegistry(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
|
||||
TryOpenKey(HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE", NULL, output);
|
||||
TryOpenKey(HKEY_CURRENT_USER, L"HKEY_CURRENT_USER", NULL, output);
|
||||
TryOpenKey(HKEY_USERS, L"HKEY_USERS", NULL, output);
|
||||
TryOpenKey(HKEY_LOCAL_MACHINE,
|
||||
L"HKEY_LOCAL_MACHINE",
|
||||
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
|
||||
output);
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "sandbox/win/sandbox_poc/pocdll/exports.h"
|
||||
#include "sandbox/win/sandbox_poc/pocdll/utils.h"
|
||||
|
||||
// This file contains the tests used to verify the security of the system by
|
||||
// using some spying techniques.
|
||||
|
||||
void POCDLL_API TestSpyKeys(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
|
||||
if (RegisterHotKey(NULL, 1, 0, 0x42)) {
|
||||
fprintf(output, "[GRANTED] successfully registered hotkey\r\n");
|
||||
UnregisterHotKey(NULL, 1);
|
||||
} else {
|
||||
fprintf(output, "[BLOCKED] Failed to register hotkey. Error = %ld\r\n",
|
||||
::GetLastError());
|
||||
}
|
||||
|
||||
fprintf(output, "[INFO] Logging keystrokes for 15 seconds\r\n");
|
||||
fflush(output);
|
||||
std::wstring logged;
|
||||
DWORD tick = ::GetTickCount() + 15000;
|
||||
while (tick > ::GetTickCount()) {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
if (::GetAsyncKeyState(i) & 1) {
|
||||
if (i >= VK_SPACE && i <= 0x5A /*VK_Z*/) {
|
||||
logged.append(1, static_cast<wchar_t>(i));
|
||||
} else {
|
||||
logged.append(1, '?');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (logged.size()) {
|
||||
fprintf(output, "[GRANTED] Spyed keystrokes \"%S\"\r\n",
|
||||
logged.c_str());
|
||||
} else {
|
||||
fprintf(output, "[BLOCKED] Spyed keystrokes \"(null)\"\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void POCDLL_API TestSpyScreen(HANDLE log) {
|
||||
HandleToFile handle2file;
|
||||
FILE *output = handle2file.Translate(log, "w");
|
||||
|
||||
HDC screen_dc = ::GetDC(NULL);
|
||||
COLORREF pixel_color = ::GetPixel(screen_dc, 0, 0);
|
||||
|
||||
for (int x = 0; x < 10; ++x) {
|
||||
for (int y = 0; y < 10; ++y) {
|
||||
if (::GetPixel(screen_dc, x, y) != pixel_color) {
|
||||
fprintf(output, "[GRANTED] Read pixel on screen\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output, "[BLOCKED] Read pixel on screen. Error = %ld\r\n",
|
||||
::GetLastError());
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SANDBOX_WIN_SANDBOX_POC_POCDLL_UTILS_H_
|
||||
#define SANDBOX_WIN_SANDBOX_POC_POCDLL_UTILS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
|
||||
// Class to convert a HANDLE to a FILE *. The FILE * is closed when the
|
||||
// object goes out of scope
|
||||
class HandleToFile {
|
||||
public:
|
||||
HandleToFile() { file_ = nullptr; }
|
||||
|
||||
HandleToFile(const HandleToFile&) = delete;
|
||||
HandleToFile& operator=(const HandleToFile&) = delete;
|
||||
|
||||
// Note: c_file_handle_ does not need to be closed because fclose does it.
|
||||
~HandleToFile() {
|
||||
if (file_) {
|
||||
fflush(file_);
|
||||
fclose(file_);
|
||||
}
|
||||
}
|
||||
|
||||
// Translates a HANDLE (handle) to a FILE * opened with the mode "mode".
|
||||
// The return value is the FILE * or NULL if there is an error.
|
||||
FILE* Translate(HANDLE handle, const char *mode) {
|
||||
if (file_) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE new_handle;
|
||||
BOOL result = ::DuplicateHandle(::GetCurrentProcess(),
|
||||
handle,
|
||||
::GetCurrentProcess(),
|
||||
&new_handle,
|
||||
0, // Don't ask for a specific
|
||||
// desired access.
|
||||
FALSE, // Not inheritable.
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
|
||||
if (!result) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int c_file_handle = _open_osfhandle(reinterpret_cast<LONG_PTR>(new_handle),
|
||||
0); // No flags
|
||||
if (-1 == c_file_handle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file_ = _fdopen(c_file_handle, mode);
|
||||
return file_;
|
||||
}
|
||||
private:
|
||||
// the FILE* returned. We need to closed it at the end.
|
||||
FILE* file_;
|
||||
};
|
||||
|
||||
#endif // SANDBOX_WIN_SANDBOX_POC_POCDLL_UTILS_H_
|
@ -1,39 +0,0 @@
|
||||
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SANDBOX_WIN_SANDBOX_POC_RESOURCE_H_
|
||||
#define SANDBOX_WIN_SANDBOX_POC_RESOURCE_H_
|
||||
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by sandbox.rc
|
||||
//
|
||||
#define IDI_SANDBOX 107
|
||||
#define IDR_MENU_MAIN_UI 129
|
||||
#define IDD_LAUNCH_DLL 130
|
||||
#define IDC_RADIO_POCDLL 1000
|
||||
#define IDC_RADIO_CUSTOM_DLL 1001
|
||||
#define IDC_DLL_NAME 1002
|
||||
#define IDC_ENTRY_POINT 1003
|
||||
#define IDC_LOG_FILE 1004
|
||||
#define IDC_BROWSE_DLL 1005
|
||||
#define IDC_BROWSE_LOG 1006
|
||||
#define ID_FILE_EXIT 32771
|
||||
#define ID_COMMANDS_LAUNCHDLL 32772
|
||||
#define ID_COMMANDS_SPAWNTARGET 32773
|
||||
#define IDC_STATIC -1
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 131
|
||||
#define _APS_NEXT_COMMAND_VALUE 32774
|
||||
#define _APS_NEXT_CONTROL_VALUE 1007
|
||||
#define _APS_NEXT_SYMED_VALUE 110
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // SANDBOX_WIN_SANDBOX_POC_RESOURCE_H_
|
@ -1,185 +0,0 @@
|
||||
// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sandbox/win/sandbox_poc/sandbox.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "sandbox/win/sandbox_poc/main_ui_window.h"
|
||||
#include "sandbox/win/src/sandbox.h"
|
||||
#include "sandbox/win/src/sandbox_factory.h"
|
||||
|
||||
// Prototype allowed for functions to be called in the POC
|
||||
typedef void(__cdecl *lpfnInit)(HANDLE);
|
||||
|
||||
bool ParseCommandLine(wchar_t* command_line,
|
||||
std::string* dll_name,
|
||||
std::string* entry_point,
|
||||
std::wstring* log_file) {
|
||||
DCHECK(dll_name);
|
||||
DCHECK(entry_point);
|
||||
DCHECK(log_file);
|
||||
if (!dll_name || !entry_point || !log_file)
|
||||
return false;
|
||||
|
||||
LPWSTR* arg_list;
|
||||
int arg_count;
|
||||
|
||||
// We expect the command line to contain: EntryPointName "DLLPath" "LogPath"
|
||||
// NOTE: Double quotes are required, even if long path name not used
|
||||
// NOTE: LogPath can be blank, but still requires the double quotes
|
||||
arg_list = CommandLineToArgvW(command_line, &arg_count);
|
||||
if (NULL == arg_list || arg_count < 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::wstring entry_point_wide = arg_list[1];
|
||||
std::wstring dll_name_wide = arg_list[2];
|
||||
*entry_point = std::string(entry_point_wide.begin(), entry_point_wide.end());
|
||||
*dll_name = std::string(dll_name_wide.begin(), dll_name_wide.end());
|
||||
*log_file = arg_list[3];
|
||||
|
||||
// Free memory allocated for CommandLineToArgvW arguments.
|
||||
LocalFree(arg_list);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, wchar_t* command_line,
|
||||
int show_command) {
|
||||
sandbox::BrokerServices* broker_service =
|
||||
sandbox::SandboxFactory::GetBrokerServices();
|
||||
sandbox::ResultCode result;
|
||||
|
||||
// This application starts as the broker; an application with a UI that
|
||||
// spawns an instance of itself (called a 'target') inside the sandbox.
|
||||
// Before spawning a hidden instance of itself, the application will have
|
||||
// asked the user which DLL the spawned instance should load and passes
|
||||
// that as command line argument to the spawned instance.
|
||||
//
|
||||
// We check here to see if we can retrieve a pointer to the BrokerServices,
|
||||
// which is not possible if we are running inside the sandbox under a
|
||||
// restricted token so it also tells us which mode we are in. If we can
|
||||
// retrieve the pointer, then we are the broker, otherwise we are the target
|
||||
// that the broker launched.
|
||||
if (NULL != broker_service) {
|
||||
// Yes, we are the broker so we need to initialize and show the UI
|
||||
if (0 != (result = broker_service->Init())) {
|
||||
::MessageBox(NULL, L"Failed to initialize the BrokerServices object",
|
||||
L"Error during initialization", MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
wchar_t exe_name[MAX_PATH];
|
||||
if (0 == GetModuleFileName(NULL, exe_name, MAX_PATH - 1)) {
|
||||
::MessageBox(NULL, L"Failed to get name of current EXE",
|
||||
L"Error during initialization", MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// The CreateMainWindowAndLoop() call will not return until the user closes
|
||||
// the application window (or selects File\Exit).
|
||||
MainUIWindow window;
|
||||
window.CreateMainWindowAndLoop(instance,
|
||||
exe_name,
|
||||
show_command,
|
||||
broker_service);
|
||||
|
||||
|
||||
// Cannot exit until we have cleaned up after all the targets we have
|
||||
// created
|
||||
broker_service->WaitForAllTargets();
|
||||
} else {
|
||||
// This is an instance that has been spawned inside the sandbox by the
|
||||
// broker, so we need to parse the command line to figure out which DLL to
|
||||
// load and what entry point to call
|
||||
sandbox::TargetServices* target_service
|
||||
= sandbox::SandboxFactory::GetTargetServices();
|
||||
|
||||
if (NULL == target_service) {
|
||||
// TODO(finnur): write the failure to the log file
|
||||
// We cannot display messageboxes inside the sandbox unless access to
|
||||
// the desktop handle has been granted to us, and we don't have a
|
||||
// console window to write to. Therefore we need to have the broker
|
||||
// grant us access to a handle to a logfile and write the error that
|
||||
// occurred into the log before continuing
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Debugging the spawned application can be tricky, because DebugBreak()
|
||||
// and _asm int 3 cause the app to terminate (due to a flag in the job
|
||||
// object), MessageBoxes() will not be displayed unless we have been granted
|
||||
// that privilege and the target finishes its business so quickly we cannot
|
||||
// attach to it quickly enough. Therefore, you can uncomment the
|
||||
// following line and attach (w. msdev or windbg) as the target is sleeping
|
||||
|
||||
// Sleep(10000);
|
||||
|
||||
if (sandbox::SBOX_ALL_OK != (result = target_service->Init())) {
|
||||
// TODO(finnur): write the initialization error to the log file
|
||||
return -2;
|
||||
}
|
||||
|
||||
// Parse the command line to find out what we need to call
|
||||
std::string dll_name, entry_point;
|
||||
std::wstring log_file;
|
||||
if (!ParseCommandLine(GetCommandLineW(),
|
||||
&dll_name,
|
||||
&entry_point,
|
||||
&log_file)) {
|
||||
// TODO(finnur): write the failure to the log file
|
||||
return -3;
|
||||
}
|
||||
|
||||
// Open the pipe to transfert the log output
|
||||
HANDLE pipe = ::CreateFile(log_file.c_str(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, // Default security attributes.
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL); // No template
|
||||
|
||||
if (INVALID_HANDLE_VALUE == pipe) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
// We now know what we should load, so load it
|
||||
HMODULE dll_module = ::LoadLibraryA(dll_name.c_str());
|
||||
if (dll_module == NULL) {
|
||||
// TODO(finnur): write the failure to the log file
|
||||
CloseHandle(pipe);
|
||||
return -5;
|
||||
}
|
||||
|
||||
// Initialization is finished, so we can enter lock-down mode
|
||||
target_service->LowerToken();
|
||||
|
||||
lpfnInit init_function =
|
||||
(lpfnInit) ::GetProcAddress(dll_module, entry_point.c_str());
|
||||
|
||||
if (!init_function) {
|
||||
// TODO(finnur): write the failure to the log file
|
||||
::FreeLibrary(dll_module);
|
||||
CloseHandle(pipe);
|
||||
return -6;
|
||||
}
|
||||
|
||||
// Transfer control to the entry point in the DLL requested
|
||||
init_function(pipe);
|
||||
|
||||
CloseHandle(pipe);
|
||||
Sleep(1000); // Give a change to the debug output to arrive before the
|
||||
// end of the process
|
||||
|
||||
::FreeLibrary(dll_module);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SANDBOX_WIN_SANDBOX_POC_SANDBOX_H_
|
||||
#define SANDBOX_WIN_SANDBOX_POC_SANDBOX_H_
|
||||
|
||||
#include "sandbox/win/sandbox_poc/resource.h"
|
||||
|
||||
#endif // SANDBOX_WIN_SANDBOX_POC_SANDBOX_H_
|
Binary file not shown.
Before (image error) Size: 1.1 KiB |
@ -1,136 +0,0 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_MENU_MAIN_UI MENU
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "E&xit", ID_FILE_EXIT
|
||||
END
|
||||
POPUP "&Commands"
|
||||
BEGIN
|
||||
MENUITEM "&Spawn target", ID_COMMANDS_SPAWNTARGET
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_LAUNCH_DLL DIALOGEX 0, 0, 269, 118
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "BrokerUI: Load an Attack DLL"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Call now",IDOK,212,70,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,212,95,50,14
|
||||
EDITTEXT IDC_DLL_NAME,7,43,200,13,ES_AUTOHSCROLL
|
||||
LTEXT "DLL to load in target:",IDC_STATIC,7,33,168,8
|
||||
LTEXT "Function to call:",IDC_STATIC,7,61,139,8
|
||||
EDITTEXT IDC_ENTRY_POINT,7,71,200,13,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_LOG_FILE,7,17,200,13,ES_AUTOHSCROLL
|
||||
LTEXT "File for Target logging (optional):",IDC_STATIC,7,7,139,8
|
||||
PUSHBUTTON "Browse...",IDC_BROWSE_DLL,212,42,50,14
|
||||
PUSHBUTTON "Browse...",IDC_BROWSE_LOG,212,16,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_LAUNCH_DLL, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 262
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 111
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_SANDBOX ICON "sandbox.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
@ -1,202 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="sandbox_poc"
|
||||
ProjectGUID="{CF757839-F2A1-417C-8F25-DCAE480020F1}"
|
||||
RootNamespace="sandbox_poc"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;$(SolutionDir)..\build\common.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="2"
|
||||
ForcedIncludeFiles="stdafx.h"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;$(SolutionDir)..\build\common.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\main_ui_window.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\main_ui_window.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sandbox.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sandbox.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sandbox.ico"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sandbox.rc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
Reference in New Issue
Block a user