Sandbox Design && Implementation Principles

catalog

1. sandbox introduction
2. Sandboxie
3. seccomp(short for secure computing mode): API级沙箱
4. 利用do_syscall_trace一次性对所有系统调用进行Hook监控

 

1. sandbox introduction

在计算机安全领域,沙盒(sandbox 沙箱)是一种安全机制,为运行中的程序提供的隔离环境。通常是作为一些来源不可信、具破坏力或无法判定程序意图的程序提供实验之用
沙盒通常严格控制其中的程序所能访问的资源,比如,沙盒可以提供用后即回收的磁盘及内存空间。在沙盒中,网络访问、对真实系统的访问、对输入设备的读取通常被禁止或是严格限制。从这个角度来说,沙盒属于虚拟化的一种,沙盒中的所有改动对操作系统不会造成任何损失。通常,这种技术被计算机技术人员广泛用于测试可能带毒的程序或是其他的恶意代码

有时沙盒也叫沙箱,英文sandbox。在计算机领域指一种虚拟技术,且多用于计算机安全技术。其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中。当某个程序试图发挥作用时,安全软件可以先让它在沙盒中运行,如果含有恶意行为,则禁止程序的进一步运行,而这不会对系统造成任何危害

0x1: sandbox具体实现形式

沙盒将软件运行于一个受限的系统环境中,控制程序可使用的资源(如文件描述符、内存、磁盘空间等),以下是一些沙盒的具体实现

1. chroot 
chroot是在unix系统的一个操作,针对正在运作的软件进程和它的子进程,改变它外显的根目录。一个运行在这个环境下,经由chroot设置根目录的程序,它不能够对这个指定根目录之外的文件进行访问动作,不能读取,也不能更改它的内容,由chroot创造出的那个根目录,叫做"chroot监狱"(chroot jail / chroot prison)

2. Sandboxie
Sandboxie是一个沙盒计算机程序用于将浏览器限制在一个虚拟沙箱中运行,由Ronen Tzur开发,可以在32位及64位的、基于Windows NT的系统上运行(如Windows XP、Windows 7等)。它创造了一个类似沙盒的独立作业环境,在其内部运行的程序并不能对硬盘产生永久性的影响。其为一个独立的虚拟环境,可用以测试不受信任的应用程序或上网行为

3. 软件监狱(Jail)
限制网络访问、受限的文件系统命名空间。软件监狱最常用于虚拟主机上(例如VM)

4. LSM MAC访问控制
基于规则的执行,通过系统安全机制,按照一系列预设规则给用户及程序分配一定的访问权限,完全控制程序的启动、代码注入及网络访问。也可控制程序对于文件、注册表的访问。在这样的环境中,病毒木马感染系统的几率将会减小。Linux中,安全增强式Linux和AppArmor正使用了这种策略

5. 虚拟机
模拟一个完整的宿主系统,可以如运行于真实硬件一般运行虚拟的操作系统(客户系统)。客户系统只能通过模拟器访问宿主的资源,因此可算作一种沙盒

6. 主机本地沙盒
通过创建一个模拟真实桌面的环境,研究人员就能够观察恶意软件是如何感染一台主机的。若干恶意软件分析服务使用了沙盒技术,例如Docker技术就是一种典型的用户态沙盒,在Docker容器中的操作被严格进行配置和限制

7. 安全计算模式(seccomp)
Linux内核内置的一个沙盒。启用后,seccomp仅允许write()、read()、exit()和sigreturn()这几个系统调用。

8. KERNEL级Sandbox
一种类似于影子系统的,比带有宿主的虚拟机更深层的系统内核级技术。它可以接管病毒调用接口或函数的行为。并会在确认病毒行为后实行回滚机制,让系统复原 

0x2: sandbox技术思想

1. 将对数据的修改、对系统的操作重定向到一个受保护的虚拟区域
2. ROLLBACK(回滚),当发生策略规定范围之外的操作事件时,及时对异常状态进行回滚
3. 策略限制,例如defensewall、SELINUX、AppArmor、Smack

Relevant Link:

http://zh.wikipedia.org/wiki/Chroot
http://zh.wikipedia.org/wiki/Sandboxie
http://lifehacker.com/sandboxie-tests-apps-without-risking-your-system-now-s-514339469
http://sandboxie.com/index.php?AllVersions
http://baike.baidu.com/view/7373858.htm
http://zh.wikipedia.org/wiki/%E6%B2%99%E7%9B%92_(%E9%9B%BB%E8%85%A6%E5%AE%89%E5%85%A8)

 

2. Sandboxie

技术分享

Relevant Link:

http://www.sandboxie.com/index.php?HowItWorks
http://www.cnblogs.com/SunboyL/p/SandBox.html

 

3. seccomp(short for secure computing mode): API级沙箱

seccomp (short for secure computing mode) is a computer security facility that provides an application sandboxing mechanism in the Linux kernel; it was merged into the Linux kernel mainline in kernel version 2.6.12, which was released on March 8, 2005.seccomp allows a process to make a one-way transition into a "secure" state where it cannot make any system calls except exit(), sigreturn(), read() and write() to already-open file descriptors. Should it attempt any other system calls, the kernel will terminate the process with SIGKILL. In this sense, it does not virtualize the system‘s resources but isolates the process from them entirely.

#include <sys/prctl.h>
int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);

option = PR_SET_SECCOMP (since Linux 2.6.23)
Set the secure computing (seccomp) mode for the calling thread, to limit the available system calls.  The more recent seccomp(2) system call provides a superset of the functionality of PR_SET_SECCOMP.

seccomp mode is enabled via the prctl(2) system call using the PR_SET_SECCOMP argument, or (since Linux kernel 3.17) via the seccomp(2) system call.

0x1: seccomp-bpf

seccomp-bpf is an extension to seccomp that allows filtering of system calls using a configurable policy implemented using Berkeley Packet Filter rules. It is used by OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and Linux.
从本质上讲,seccomp filters相当于PHP中的"safe mode",通过提前限制进程可以使用系统API范围,来达到Jail限制沙箱的目的

0x2: Uses

1. As of Chrome version 20, seccomp-bpf is used to sandbox Adobe Flash Player 
2. As of Chrome version 23, seccomp-bpf is used to sandbox the renderers 
3. Vsftpd uses seccomp-bpf sandboxing as of version 3.0.0 
4. OpenSSH has supported seccomp-bpf since version 6.0
5. LXD, which is a "hypervisor" for containers 
6. Firefox and FirefoxOS use seccomp-bpf to sandbox the child processes and certain plugins

0x3: Detecting seccomp features at runtime

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>

int main(void)
{
        int ret;

        ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
        if (ret < 0) {
                switch (errno) {
                case ENOSYS:
                        printf("seccomp not available: pre-2.6.23\n");
                        return 0;
                case EINVAL:
                        printf("seccomp not available: not built in\n");
                        return 0;
                default:
                        fprintf(stderr, "unknown PR_GET_SECCOMP error: %s\n",
                                strerror(errno));
                        return 1;
                }
        }
        printf("seccomp available\n");

        ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
        if (ret < 0) {
                switch (errno) {
                case EINVAL:
                        printf("seccomp filter not available\n");
                        return 0;

                case EFAULT:
                        printf("seccomp filter available\n");
                        return 0;

                default:
                        fprintf(stderr, "unknown PR_SET_SECCOMP error: %s\n",
                                strerror(errno));
                        return 1;
                }
        }
        printf("PR_SET_SECCOMP unexpectedly succeeded?!\n");
        return 1;
}

0x4: Code Example Use

seccomp是操作系统通过API方式(Glibc/System call)提供的一种API调用访问控制能力,在程序开发中需要调用seccomp相关的API将这种控制能力"引入进来",可以理解为程序在编译阶段就给自己施加对应的限制,这样即使发生了溢出攻击,被Exploit的程序也会由于API沙箱的限制而无法执行太多危险操作

example.c

/*
 * seccomp example with syscall reporting
 * 
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>

#include "config.h"
#include "seccomp-bpf.h"

static int install_syscall_filter(void)
{
    struct sock_filter filter[] = 
    { 
        VALIDATE_ARCHITECTURE,        /* Validate architecture. */ 
        EXAMINE_SYSCALL,        /* Grab the system call number. */
        ALLOW_SYSCALL(rt_sigreturn),    /* List allowed syscalls. */
#ifdef __NR_sigreturn
        ALLOW_SYSCALL(sigreturn),
#endif
        ALLOW_SYSCALL(exit_group),
        ALLOW_SYSCALL(exit),
        ALLOW_SYSCALL(read),
        ALLOW_SYSCALL(write),
        KILL_PROCESS,
    };

    struct sock_fprog prog = 
    {
        .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
        .filter = filter,
    };

    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) 
    {
        perror("prctl(NO_NEW_PRIVS)");
        goto failed;
    }
    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) 
    {
        perror("prctl(SECCOMP)");
        goto failed;
    }
    return 0;

failed:
    if (errno == EINVAL)
    {
        fprintf(stderr, "SECCOMP_FILTER is not available. :(\n");
    } 
    
    return 1;
}

int main(int argc, char *argv[])
{
    char buf[1024];

    if (install_syscall_filter())
    {
        return 1;
    }     

    printf("Type stuff here: ");
    fflush(NULL);
    buf[0] = \0;
    fgets(buf, sizeof(buf), stdin);
    printf("You typed: %s", buf);

    printf("And now we fork, which should do quite the opposite ...\n");
    fflush(NULL);
    sleep(1);

    fork();
    printf("You should not see this because I‘m dead.\n");

    return 0;
}
//gcc -Wall   -c -o example.o example.c

seccomp-bpf.h

/*
 * seccomp example for x86 (32-bit and 64-bit) with BPF macros
 *
 * Copyright (c) 2012 The Chromium OS Authors <[email protected]>
 * Authors:
 *  Will Drewry <[email protected]>
 *  Kees Cook <[email protected]>
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef _SECCOMP_BPF_H_
#define _SECCOMP_BPF_H_

#define _GNU_SOURCE 1
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#include <sys/prctl.h>
#ifndef PR_SET_NO_NEW_PRIVS
# define PR_SET_NO_NEW_PRIVS 38
#endif

#include <linux/unistd.h>
#include <linux/audit.h>
#include <linux/filter.h>
#ifdef HAVE_LINUX_SECCOMP_H
# include <linux/seccomp.h>
#endif
#ifndef SECCOMP_MODE_FILTER
# define SECCOMP_MODE_FILTER    2 /* uses user-supplied filter. */
# define SECCOMP_RET_KILL    0x00000000U /* kill the task immediately */
# define SECCOMP_RET_TRAP    0x00030000U /* disallow and force a SIGSYS */
# define SECCOMP_RET_ALLOW    0x7fff0000U /* allow */
struct seccomp_data {
    int nr;
    __u32 arch;
    __u64 instruction_pointer;
    __u64 args[6];
};
#endif
#ifndef SYS_SECCOMP
# define SYS_SECCOMP 1
#endif

#define syscall_nr (offsetof(struct seccomp_data, nr))
#define arch_nr (offsetof(struct seccomp_data, arch))

#if defined(__i386__)
# define REG_SYSCALL    REG_EAX
# define ARCH_NR    AUDIT_ARCH_I386
#elif defined(__x86_64__)
# define REG_SYSCALL    REG_RAX
# define ARCH_NR    AUDIT_ARCH_X86_64
#else
# warning "Platform does not support seccomp filter yet"
# define REG_SYSCALL    0
# define ARCH_NR    0
#endif

#define VALIDATE_ARCHITECTURE \
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr),     BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0),     BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)

#define EXAMINE_SYSCALL \
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr)

#define ALLOW_SYSCALL(name) \
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1),     BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)

#define KILL_PROCESS \
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)

#endif /* _SECCOMP_BPF_H_ */

技术分享

Relevant Link:

http://outflux.net/teach-seccomp/
http://man7.org/linux/man-pages/man2/prctl.2.html
http://en.wikipedia.org/wiki/Seccomp
https://blog.jtlebi.fr/2014/05/29/introduction-to-seccomp-bpf-linux-syscall-filter/#comment-135514
http://outflux.net/teach-seccomp/autodetect.html

 

4. 利用do_syscall_trace一次性对所有系统调用进行Hook监控

Relevant Link:

http://blog.aliyun.com/948

 

Copyright (c) 2015 LittleHann All rights reserved

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。