0

[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:
James Forshaw
2021-11-15 17:45:51 +00:00
committed by Chromium LUCI CQ
parent eded28bbff
commit 0de7fda233
22 changed files with 0 additions and 2858 deletions

@ -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>