diff --git a/README.md b/README.md
index dcce738..3ea07cf 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,66 @@ Secure import for python modules using dtrace under the hood.
# Quick Start
+`secimport` can be used out of the box in the following ways:
+1. Inside your code using `module = secimport.secure_import('module_name', ...)`.
+ - Replacing the regular `import` statement with `secure_import`
+ - Only modules that were imported with `secure_import` will be traced.
+2. As a sandbox, by specifying the modules and their policies.
+ - Use this repository to:
+ - Generate a YAML policy from your code
+ - Compile that YAML to dscript.
+ - Use `dtrace` command to run your main python application, with your tailor-made sandbox.
+ - No need for `secure_import`, you can keep using regular `import`s
+
For the full list of examples, see EXAMPLES.md.
+# Pickle Example
+### How pickle can be exploited in your 3rd party packages:
+```python
+>>> import pickle
+>>> class Demo:
+... def __reduce__(self):
+... return (eval, ("__import__('os').system('echo Exploited!')",))
+...
+>>> pickle.dumps(Demo())
+b"\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c*__import__('os').system('echo Exploited!')\x94\x85\x94R\x94."
+>>> pickle.loads(b"\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c*__import__('os').system('echo Exploited!')\x94\x85\x94R\x94.")
+Exploited!
+0
+```
+With `secimport`, you can control such action to do whatever you want:
+```python
+In [1]: import secimport
+In [2]: pickle = secimport.secure_import("pickle")
+In [3]: pickle.loads(b"\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c*__import__('os').system('echo Exploited!')\x94\x85\x94R\x94.")
+
+[1] 28027 killed ipython
+```
+A log file is automatically created, containing everything you need to know:
+```
+$ less /tmp/.secimport/sandbox_pickle.log
+
+ @posix_spawn from /Users/avilumelsky/Downloads/Python-3.10.0/Lib/threading.py
+ DETECTED SHELL:
+ depth=8
+ sandboxed_depth=0
+ sandboxed_module=/Users/avilumelsky/Downloads/Python-3.10.0/Lib/pickle.py
+
+ TERMINATING SHELL:
+ libsystem_kernel.dylib`__posix_spawn+0xa
+ ...
+ libsystem_kernel.dylib`__posix_spawn+0xa
+ libsystem_c.dylib`system+0x18b
+ python.exe`os_system+0xb3
+ KILLED
+:
+```
+
## YAML Template Example
+For a full tutorial, see YAML Profiles Usage
```shell
+# An example yaml template for a sandbox.
+
modules:
requests:
destructive: true
@@ -45,9 +101,8 @@ modules:
- stat64
```
-See YAML Profiles Usage
-## Python Shell Interactive Example
+## Python Processing Example
```python
Python 3.10.0 (default, May 2 2022, 21:43:20) [Clang 13.0.0 (clang-1300.0.27.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
@@ -93,7 +148,7 @@ Type "help", "copyright", "credits" or "license" for more information.
killed.
```
-## Shell blocking
+## Shell Blocking Example
```python
# example.py - Executes code upon import;
import os;
@@ -117,7 +172,7 @@ Killed: 9
- If a syscall like `spawn/exec/fork/forkexec` will be executed
- The process will be `kill`ed with `-9` signal.
-## Network blocking
+## Network Blocking Example
```
>>> import requests
>>> requests.get('https://google.com')
@@ -166,11 +221,11 @@ Not related for python, but for the sake of explanation (Equivilant Demo soon).
## TODO:
+- ✔️ Allow/Block list configuration
+- ✔️ Create a .yaml configuration per module in the code
+ - ✔️ Use secimport to compile that yml
+ - ✔️ Create a single dcript policy
+ - ✔️ Run an application with that policy using dtrace, without using `secure_import`
- Node support (dtrace hooks)
- Go support (dtrace hooks)
-- Allow/Block list configuration
- Use current_module_str together with thread ID
-- Create a .yaml configuration per module in the code
- - Use secimport to compile that yml
- - Create a single dcript policy
- - Run an application with that policy using dtrace, without using `secure_import`
diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md
index aaca369..73fac5e 100644
--- a/docs/EXAMPLES.md
+++ b/docs/EXAMPLES.md
@@ -9,7 +9,7 @@ To understand how to trace you process and create custom profiles for modules or
- YAML to Sandbox Example
- `examples/create_profile_from_yaml.sh`
- Create a sandbox template code for your app from a single YAML file.
- - See YAML Profiles Usage
+ - See YAML Profiles Usage
- Python (import inline):
- `requests` example - secure import vs regular import (Killed because of socket related syscall)
- `python examples/http_request.py`
diff --git a/docs/TRACING_PROCESSES.md b/docs/TRACING_PROCESSES.md
index 14b5b7b..34b28c4 100644
--- a/docs/TRACING_PROCESSES.md
+++ b/docs/TRACING_PROCESSES.md
@@ -1,7 +1,7 @@
# Tracing processes for syscalls
There are several ways to create a secimport profile for your modules.
- - Using a YAML template
- - See YAML Profiles Usage
+ - Using a YAML build
+ - See YAML Profiles Usage
- Using `secure_import` from python:
- `secimport.secure_import(..., log_syscalls=True, destructive=False)`
- The log output will contain all the syscalls made by your process.
diff --git a/pyproject.toml b/pyproject.toml
index a6c3636..952e4ef 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "secimport"
-version = "0.4.1"
+version = "0.4.2"
description = "A sandbox/supervisor for python modules."
authors = ["Avi Lumelsky"]
license = "MIT"
diff --git a/src/secimport/templates/actions/kill_on_processing.d b/src/secimport/templates/actions/kill_on_processing.d
index f5c2a90..40bbfd9 100644
--- a/src/secimport/templates/actions/kill_on_processing.d
+++ b/src/secimport/templates/actions/kill_on_processing.d
@@ -1,10 +1,8 @@
- printf("\t\t\t\tDETECTED SHELL, depth=%d sandboxed_depth=%d\r\n", self->depth, depth_matrix["###MODULE_NAME###"]);
- if(depth_matrix["###MODULE_NAME###"] != 0 && self->depth >= depth_matrix["###MODULE_NAME###"]){
- printf("\t\tTERMINATING shell...\r\n");
- ustack();
- stop();
- printf("\t\tKILLING...\r\n");
- system("\t\tkill -9 %d", pid);
- printf("\t\tKILLED.\r\n");
- exit(-1);
- }
\ No newline at end of file
+ printf("\t\t\t\tDETECTED SHELL, depth=%d sandboxed_depth=%d sandboxed_module=%s current_module=%s\r\n", self->depth, depth_matrix["###MODULE_NAME###"], "###MODULE_NAME###", _current_module_str);
+ printf("\t\tTERMINATING shell...\r\n");
+ ustack();
+ stop();
+ printf("\t\tKILLING...\r\n");
+ system("\t\tkill -9 %d", pid);
+ printf("\t\tKILLED.\r\n");
+ exit(-1);
\ No newline at end of file
diff --git a/src/secimport/templates/actions/log_syscall.d b/src/secimport/templates/actions/log_syscall.d
index f03cd59..63d40b4 100644
--- a/src/secimport/templates/actions/log_syscall.d
+++ b/src/secimport/templates/actions/log_syscall.d
@@ -1 +1 @@
- printf("\n@%s", probefunc);
\ No newline at end of file
+ printf("\n@%s from %s", probefunc, current_module_str);
\ No newline at end of file
diff --git a/tests/test_sandbox_helper.py b/tests/test_sandbox_helper.py
index 515dbb5..e16c6ec 100644
--- a/tests/test_sandbox_helper.py
+++ b/tests/test_sandbox_helper.py
@@ -243,3 +243,7 @@ def test_build_module_sandbox_from_yaml_template(self):
self.assertIsInstance(module_sandbox_code, str)
self.assertFalse("###SUPERVISED_MODULES_PROBES###" in module_sandbox_code)
+
+
+if __name__ == '__main__':
+
\ No newline at end of file