seccomp-tools 1.1.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +112 -30
- data/bin/seccomp-tools +1 -0
- data/ext/ptrace/extconf.rb +2 -0
- data/ext/ptrace/ptrace.c +107 -5
- data/lib/seccomp-tools.rb +5 -0
- data/lib/seccomp-tools/asm/asm.rb +5 -2
- data/lib/seccomp-tools/asm/compiler.rb +96 -18
- data/lib/seccomp-tools/asm/tokenizer.rb +25 -8
- data/lib/seccomp-tools/bpf.rb +7 -4
- data/lib/seccomp-tools/cli/asm.rb +16 -6
- data/lib/seccomp-tools/cli/base.rb +10 -4
- data/lib/seccomp-tools/cli/cli.rb +9 -6
- data/lib/seccomp-tools/cli/disasm.rb +6 -2
- data/lib/seccomp-tools/cli/dump.rb +37 -6
- data/lib/seccomp-tools/cli/emu.rb +41 -22
- data/lib/seccomp-tools/const.rb +47 -16
- data/lib/seccomp-tools/consts/sys_arg.rb +432 -0
- data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
- data/lib/seccomp-tools/consts/{amd64.rb → sys_nr/amd64.rb} +6 -1
- data/lib/seccomp-tools/consts/{i386.rb → sys_nr/i386.rb} +18 -15
- data/lib/seccomp-tools/disasm/context.rb +125 -34
- data/lib/seccomp-tools/disasm/disasm.rb +5 -2
- data/lib/seccomp-tools/dumper.rb +75 -8
- data/lib/seccomp-tools/emulator.rb +19 -8
- data/lib/seccomp-tools/instruction/alu.rb +7 -2
- data/lib/seccomp-tools/instruction/base.rb +5 -3
- data/lib/seccomp-tools/instruction/instruction.rb +2 -0
- data/lib/seccomp-tools/instruction/jmp.rb +28 -14
- data/lib/seccomp-tools/instruction/ld.rb +28 -12
- data/lib/seccomp-tools/instruction/ldx.rb +2 -0
- data/lib/seccomp-tools/instruction/misc.rb +2 -0
- data/lib/seccomp-tools/instruction/ret.rb +14 -2
- data/lib/seccomp-tools/instruction/st.rb +4 -2
- data/lib/seccomp-tools/instruction/stx.rb +2 -0
- data/lib/seccomp-tools/logger.rb +40 -0
- data/lib/seccomp-tools/syscall.rb +24 -13
- data/lib/seccomp-tools/templates/asm.amd64.asm +26 -0
- data/lib/seccomp-tools/templates/asm.c +17 -0
- data/lib/seccomp-tools/templates/asm.i386.asm +33 -0
- data/lib/seccomp-tools/util.rb +24 -3
- data/lib/seccomp-tools/version.rb +3 -1
- metadata +51 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fa755fd2e7ed97279b094dfa28bd668aef4ee638005f0b38405066502fc8a30d
|
|
4
|
+
data.tar.gz: 56b0d51796d97a89f67262c36716833d078ce19ea6b58fbb83c2f8bee88b8685
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 027f57a717cb63fadeefd4a60213115a27ed51bb1eb3e6b58251690ed7c1d42335086ff4448b480296b77d395ba2e8718fa662e227394abfddaf80b19b769b74
|
|
7
|
+
data.tar.gz: f6aca254b4a43d6c60d5df7e6694b976de1e56fbb6d6585bd46fd17c0849820d76c81f25bbc872dc785576e05eeaaab5d0276a3f065b730988973c5073ace761
|
data/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
[](https://github.com/david942j/seccomp-tools/actions)
|
|
2
|
+
[](https://dependabot.com)
|
|
2
3
|
[](https://codeclimate.com/github/david942j/seccomp-tools)
|
|
3
4
|
[](https://codeclimate.com/github/david942j/seccomp-tools)
|
|
4
5
|
[](https://codeclimate.com/github/david942j/seccomp-tools/coverage)
|
|
@@ -6,20 +7,20 @@
|
|
|
6
7
|
[](http://choosealicense.com/licenses/mit/)
|
|
7
8
|
|
|
8
9
|
# Seccomp Tools
|
|
9
|
-
|
|
10
|
+
Provide powerful tools for seccomp analysis.
|
|
10
11
|
|
|
11
12
|
This project is targeted to (but not limited to) analyze seccomp sandbox in CTF pwn challenges.
|
|
12
|
-
Some features might be CTF-specific, but still useful for
|
|
13
|
+
Some features might be CTF-specific, but still useful for analyzing seccomp in real-case.
|
|
13
14
|
|
|
14
15
|
## Features
|
|
15
|
-
* Dump - Automatically
|
|
16
|
-
* Disasm -
|
|
16
|
+
* Dump - Automatically dumps seccomp-bpf from execution file(s).
|
|
17
|
+
* Disasm - Converts bpf to human readable format.
|
|
17
18
|
- Simple decompile.
|
|
18
|
-
-
|
|
19
|
+
- Display syscall names and arguments when possible.
|
|
20
|
+
- Colorful!
|
|
19
21
|
* Asm - Write seccomp rules is so easy!
|
|
20
|
-
* Emu -
|
|
21
|
-
*
|
|
22
|
-
* Support multi-architectures.
|
|
22
|
+
* Emu - Emulates seccomp rules.
|
|
23
|
+
* Supports multi-architectures.
|
|
23
24
|
|
|
24
25
|
## Installation
|
|
25
26
|
|
|
@@ -28,6 +29,12 @@ Available on RubyGems.org!
|
|
|
28
29
|
$ gem install seccomp-tools
|
|
29
30
|
```
|
|
30
31
|
|
|
32
|
+
If you failed when compiling, try:
|
|
33
|
+
```
|
|
34
|
+
sudo apt install gcc ruby-dev
|
|
35
|
+
```
|
|
36
|
+
and install seccomp-tools again.
|
|
37
|
+
|
|
31
38
|
## Command Line Interface
|
|
32
39
|
|
|
33
40
|
### seccomp-tools
|
|
@@ -38,19 +45,21 @@ $ seccomp-tools --help
|
|
|
38
45
|
#
|
|
39
46
|
# List of commands:
|
|
40
47
|
#
|
|
41
|
-
# dump Automatically dump seccomp bpf from execution file.
|
|
42
|
-
# disasm Disassemble seccomp bpf.
|
|
43
48
|
# asm Seccomp bpf assembler.
|
|
49
|
+
# disasm Disassemble seccomp bpf.
|
|
50
|
+
# dump Automatically dump seccomp bpf from execution file(s).
|
|
44
51
|
# emu Emulate seccomp rules.
|
|
45
52
|
#
|
|
46
|
-
# See 'seccomp-tools
|
|
53
|
+
# See 'seccomp-tools <command> --help' to read about a specific subcommand.
|
|
47
54
|
|
|
48
|
-
$ seccomp-tools --help
|
|
49
|
-
# dump - Automatically dump seccomp bpf from execution file.
|
|
55
|
+
$ seccomp-tools dump --help
|
|
56
|
+
# dump - Automatically dump seccomp bpf from execution file(s).
|
|
57
|
+
# NOTE : This function is only available on Linux.
|
|
50
58
|
#
|
|
51
59
|
# Usage: seccomp-tools dump [exec] [options]
|
|
52
60
|
# -c, --sh-exec <command> Executes the given command (via sh).
|
|
53
61
|
# Use this option if want to pass arguments or do pipe things to the execution file.
|
|
62
|
+
# e.g. use `-c "./bin > /dev/null"` to dump seccomp without being mixed with stdout.
|
|
54
63
|
# -f, --format FORMAT Output format. FORMAT can only be one of <disasm|raw|inspect>.
|
|
55
64
|
# Default: disasm
|
|
56
65
|
# -l, --limit LIMIT Limit the number of calling "prctl(PR_SET_SECCOMP)".
|
|
@@ -60,12 +69,14 @@ $ seccomp-tools --help dump
|
|
|
60
69
|
# If multiple seccomp syscalls have been invoked (see --limit),
|
|
61
70
|
# results will be written to FILE, FILE_1, FILE_2.. etc.
|
|
62
71
|
# For example, "--output out.bpf" and the output files are out.bpf, out_1.bpf, ...
|
|
72
|
+
# -p, --pid PID Dump installed seccomp filters of the existing process.
|
|
73
|
+
# You must have CAP_SYS_ADMIN (e.g. be root) in order to use this option.
|
|
63
74
|
|
|
64
75
|
```
|
|
65
76
|
|
|
66
77
|
### dump
|
|
67
78
|
|
|
68
|
-
|
|
79
|
+
Dumps the seccomp bpf from an execution file.
|
|
69
80
|
This work is done by the `ptrace` syscall.
|
|
70
81
|
|
|
71
82
|
NOTICE: beware of the execution file will be executed.
|
|
@@ -113,7 +124,7 @@ $ seccomp-tools dump spec/binary/twctf-2016-diary -f raw | xxd
|
|
|
113
124
|
|
|
114
125
|
### disasm
|
|
115
126
|
|
|
116
|
-
|
|
127
|
+
Disassembles the seccomp from raw bpf.
|
|
117
128
|
```bash
|
|
118
129
|
$ xxd spec/data/twctf-2016-diary.bpf | head -n 3
|
|
119
130
|
# 00000000: 2000 0000 0000 0000 1500 0001 0200 0000 ...............
|
|
@@ -146,26 +157,27 @@ $ seccomp-tools disasm spec/data/twctf-2016-diary.bpf
|
|
|
146
157
|
|
|
147
158
|
### asm
|
|
148
159
|
|
|
149
|
-
|
|
150
|
-
|
|
160
|
+
Assembles the seccomp rules into raw bytes.
|
|
161
|
+
It's very useful when one wants to write custom seccomp rules.
|
|
151
162
|
|
|
152
|
-
Supports labels for jumping and
|
|
163
|
+
Supports labels for jumping and uses syscall names directly. See examples below.
|
|
153
164
|
```bash
|
|
154
165
|
$ seccomp-tools asm
|
|
155
166
|
# asm - Seccomp bpf assembler.
|
|
156
167
|
#
|
|
157
168
|
# Usage: seccomp-tools asm IN_FILE [options]
|
|
158
169
|
# -o, --output FILE Output result into FILE instead of stdout.
|
|
159
|
-
# -f, --format FORMAT Output format. FORMAT can only be one of <inspect|raw|
|
|
170
|
+
# -f, --format FORMAT Output format. FORMAT can only be one of <inspect|raw|c_array|c_source|assembly>.
|
|
160
171
|
# Default: inspect
|
|
161
172
|
# -a, --arch ARCH Specify architecture.
|
|
162
|
-
# Supported architectures are <amd64|i386>.
|
|
173
|
+
# Supported architectures are <aarch64|amd64|i386>.
|
|
174
|
+
# Default: amd64
|
|
163
175
|
|
|
164
176
|
# Input file for asm
|
|
165
177
|
$ cat spec/data/libseccomp.asm
|
|
166
178
|
# # check if arch is X86_64
|
|
167
179
|
# A = arch
|
|
168
|
-
# A ==
|
|
180
|
+
# A == ARCH_X86_64 ? next : dead
|
|
169
181
|
# A = sys_number
|
|
170
182
|
# A >= 0x40000000 ? dead : next
|
|
171
183
|
# A == write ? ok : next
|
|
@@ -181,8 +193,52 @@ $ cat spec/data/libseccomp.asm
|
|
|
181
193
|
$ seccomp-tools asm spec/data/libseccomp.asm
|
|
182
194
|
# " \x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\b>\x00\x00\xC0 \x00\x00\x00\x00\x00\x00\x005\x00\x06\x00\x00\x00\x00@\x15\x00\x04\x00\x01\x00\x00\x00\x15\x00\x03\x00\x03\x00\x00\x00\x15\x00\x02\x00 \x00\x00\x00\x15\x00\x01\x00<\x00\x00\x00\x06\x00\x00\x00\x05\x00\x05\x00\x06\x00\x00\x00\x00\x00\xFF\x7F\x06\x00\x00\x00\x00\x00\x00\x00"
|
|
183
195
|
|
|
184
|
-
$ seccomp-tools asm spec/data/libseccomp.asm -f
|
|
185
|
-
#
|
|
196
|
+
$ seccomp-tools asm spec/data/libseccomp.asm -f c_source
|
|
197
|
+
# #include <linux/seccomp.h>
|
|
198
|
+
# #include <stdio.h>
|
|
199
|
+
# #include <stdlib.h>
|
|
200
|
+
# #include <sys/prctl.h>
|
|
201
|
+
#
|
|
202
|
+
# static void install_seccomp() {
|
|
203
|
+
# static unsigned char filter[] = {32,0,0,0,4,0,0,0,21,0,0,8,62,0,0,192,32,0,0,0,0,0,0,0,53,0,6,0,0,0,0,64,21,0,4,0,1,0,0,0,21,0,3,0,3,0,0,0,21,0,2,0,32,0,0,0,21,0,1,0,60,0,0,0,6,0,0,0,5,0,5,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0};
|
|
204
|
+
# struct prog {
|
|
205
|
+
# unsigned short len;
|
|
206
|
+
# unsigned char *filter;
|
|
207
|
+
# } rule = {
|
|
208
|
+
# .len = sizeof(filter) >> 3,
|
|
209
|
+
# .filter = filter
|
|
210
|
+
# };
|
|
211
|
+
# if(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { perror("prctl(PR_SET_NO_NEW_PRIVS)"); exit(2); }
|
|
212
|
+
# if(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &rule) < 0) { perror("prctl(PR_SET_SECCOMP)"); exit(2); }
|
|
213
|
+
# }
|
|
214
|
+
|
|
215
|
+
$ seccomp-tools asm spec/data/libseccomp.asm -f assembly
|
|
216
|
+
# install_seccomp:
|
|
217
|
+
# push rbp
|
|
218
|
+
# mov rbp, rsp
|
|
219
|
+
# push 38
|
|
220
|
+
# pop rdi
|
|
221
|
+
# push 0x1
|
|
222
|
+
# pop rsi
|
|
223
|
+
# xor eax, eax
|
|
224
|
+
# mov al, 0x9d
|
|
225
|
+
# syscall
|
|
226
|
+
# push 22
|
|
227
|
+
# pop rdi
|
|
228
|
+
# lea rdx, [rip + _filter]
|
|
229
|
+
# push rdx /* .filter */
|
|
230
|
+
# push _filter_end - _filter >> 3 /* .len */
|
|
231
|
+
# mov rdx, rsp
|
|
232
|
+
# push 0x2
|
|
233
|
+
# pop rsi
|
|
234
|
+
# xor eax, eax
|
|
235
|
+
# mov al, 0x9d
|
|
236
|
+
# syscall
|
|
237
|
+
# leave
|
|
238
|
+
# ret
|
|
239
|
+
# _filter:
|
|
240
|
+
# .ascii "\040\000\000\000\004\000\000\000\025\000\000\010\076\000\000\300\040\000\000\000\000\000\000\000\065\000\006\000\000\000\000\100\025\000\004\000\001\000\000\000\025\000\003\000\003\000\000\000\025\000\002\000\040\000\000\000\025\000\001\000\074\000\000\000\006\000\000\000\005\000\005\000\006\000\000\000\000\000\377\177\006\000\000\000\000\000\000\000"
|
|
241
|
+
# _filter_end:
|
|
186
242
|
|
|
187
243
|
|
|
188
244
|
# let's asm then disasm!
|
|
@@ -197,7 +253,7 @@ $ seccomp-tools asm spec/data/libseccomp.asm -f raw | seccomp-tools disasm -
|
|
|
197
253
|
# 0005: 0x15 0x03 0x00 0x00000003 if (A == close) goto 0009
|
|
198
254
|
# 0006: 0x15 0x02 0x00 0x00000020 if (A == dup) goto 0009
|
|
199
255
|
# 0007: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0009
|
|
200
|
-
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO
|
|
256
|
+
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
|
|
201
257
|
# 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
|
|
202
258
|
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
|
|
203
259
|
|
|
@@ -205,17 +261,18 @@ $ seccomp-tools asm spec/data/libseccomp.asm -f raw | seccomp-tools disasm -
|
|
|
205
261
|
|
|
206
262
|
### Emu
|
|
207
263
|
|
|
208
|
-
|
|
264
|
+
Emulates seccomp given `sys_nr`, `arg0`, `arg1`, etc.
|
|
209
265
|
```bash
|
|
210
266
|
$ seccomp-tools emu --help
|
|
211
267
|
# emu - Emulate seccomp rules.
|
|
212
268
|
#
|
|
213
269
|
# Usage: seccomp-tools emu [options] BPF_FILE [sys_nr [arg0 [arg1 ... arg5]]]
|
|
214
270
|
# -a, --arch ARCH Specify architecture.
|
|
215
|
-
# Supported architectures are <amd64|i386>.
|
|
271
|
+
# Supported architectures are <aarch64|amd64|i386>.
|
|
272
|
+
# Default: amd64
|
|
216
273
|
# -q, --[no-]quiet Run quietly, only show emulation result.
|
|
217
274
|
|
|
218
|
-
$ seccomp-tools emu spec/data/libseccomp.bpf 0x3
|
|
275
|
+
$ seccomp-tools emu spec/data/libseccomp.bpf write 0x3
|
|
219
276
|
# line CODE JT JF K
|
|
220
277
|
# =================================
|
|
221
278
|
# 0000: 0x20 0x00 0x00 0x00000004 A = arch
|
|
@@ -226,7 +283,7 @@ $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
|
|
|
226
283
|
# 0005: 0x15 0x03 0x00 0x00000003 if (A == close) goto 0009
|
|
227
284
|
# 0006: 0x15 0x02 0x00 0x00000020 if (A == dup) goto 0009
|
|
228
285
|
# 0007: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0009
|
|
229
|
-
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO
|
|
286
|
+
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
|
|
230
287
|
# 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
|
|
231
288
|
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
|
|
232
289
|
#
|
|
@@ -244,7 +301,32 @@ $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
|
|
|
244
301
|
|
|
245
302
|

|
|
246
303
|
|
|
304
|
+
## Architecture Supported
|
|
305
|
+
|
|
306
|
+
- [x] x86_64
|
|
307
|
+
- [x] x32
|
|
308
|
+
- [x] x86
|
|
309
|
+
- [x] arm64 (Thanks to @saagarjha!)
|
|
310
|
+
|
|
311
|
+
## Development
|
|
312
|
+
|
|
313
|
+
I recommend to use [rbenv](https://github.com/rbenv/rbenv) for your Ruby environment.
|
|
314
|
+
|
|
315
|
+
### Setup
|
|
316
|
+
|
|
317
|
+
- Install bundler
|
|
318
|
+
- `$ gem install bundler`
|
|
319
|
+
- Clone the source
|
|
320
|
+
- `$ git clone https://github.com/david942j/seccomp-tools && cd seccomp-tools`
|
|
321
|
+
- Install dependencies
|
|
322
|
+
- `$ bundle install`
|
|
323
|
+
|
|
324
|
+
### Run tests
|
|
325
|
+
|
|
326
|
+
`$ bundle exec rake`
|
|
327
|
+
|
|
247
328
|
## I Need You
|
|
329
|
+
|
|
248
330
|
Any suggestion or feature request is welcome!
|
|
249
331
|
Feel free to file an issue or send a pull request.
|
|
250
|
-
And, if you like this work, I'll be happy to be [
|
|
332
|
+
And, if you like this work, I'll be happy to be [starred](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
|
data/bin/seccomp-tools
CHANGED
data/ext/ptrace/extconf.rb
CHANGED
data/ext/ptrace/ptrace.c
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
// ptrace is only available on Linux, therefore let this file be an empty
|
|
2
|
+
// object when installing on other platforms.
|
|
3
|
+
#if __linux__
|
|
4
|
+
|
|
5
|
+
#include <assert.h>
|
|
6
|
+
#include <errno.h>
|
|
7
|
+
#include <linux/elf.h>
|
|
8
|
+
#include <linux/filter.h>
|
|
9
|
+
#include <stdint.h>
|
|
1
10
|
#include <sys/ptrace.h>
|
|
2
11
|
#include <sys/signal.h>
|
|
12
|
+
#include <sys/uio.h>
|
|
13
|
+
#include <sys/wait.h>
|
|
3
14
|
|
|
4
15
|
#include "ruby.h"
|
|
5
16
|
|
|
@@ -16,10 +27,53 @@ ptrace_peekdata(VALUE _mod, VALUE pid, VALUE addr, VALUE _data) {
|
|
|
16
27
|
return LONG2NUM(val);
|
|
17
28
|
}
|
|
18
29
|
|
|
30
|
+
// aarch64 doesn't support PTRACE_PEEKUSER, but it does support
|
|
31
|
+
// PTRACE_GETREGSET which is fairly similar. Since i386 and x86_64 support it
|
|
32
|
+
// too, just use that unconditionally to present the same API for the registers
|
|
33
|
+
// we care about.
|
|
19
34
|
static VALUE
|
|
20
|
-
ptrace_peekuser(VALUE _mod, VALUE pid, VALUE off, VALUE _data) {
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
ptrace_peekuser(VALUE _mod, VALUE pid, VALUE off, VALUE _data, VALUE bits) {
|
|
36
|
+
size_t offset = NUM2LONG(off);
|
|
37
|
+
// Unless your registers fill an entire page, an offset greater than this is
|
|
38
|
+
// probably wrong.
|
|
39
|
+
if (offset >= 4096) {
|
|
40
|
+
return LONG2NUM(-1);
|
|
41
|
+
}
|
|
42
|
+
size_t width = NUM2LONG(bits);
|
|
43
|
+
if (width != 32 && width != 64) {
|
|
44
|
+
return LONG2NUM(-1);
|
|
45
|
+
}
|
|
46
|
+
width /= 8;
|
|
47
|
+
union {
|
|
48
|
+
uint32_t val32;
|
|
49
|
+
uint64_t val64;
|
|
50
|
+
} val;
|
|
51
|
+
// Dynamically allocate a buffer to store registers-well, at least enough
|
|
52
|
+
// registers to reach the offset we want. Normally we'd want to use
|
|
53
|
+
// user_pt_regs or similar, but it's difficult to find it available in the
|
|
54
|
+
// the same header across different versions of Linux or libcs, or even with
|
|
55
|
+
// the same *name*, so this is the compromise.
|
|
56
|
+
size_t size = offset + width;
|
|
57
|
+
char *regs = malloc(size);
|
|
58
|
+
if (!regs) {
|
|
59
|
+
return LONG2NUM(-1);
|
|
60
|
+
}
|
|
61
|
+
struct iovec vec = { regs, size };
|
|
62
|
+
if (ptrace(PTRACE_GETREGSET, NUM2LONG(pid), NT_PRSTATUS, &vec) != -1 && vec.iov_len >= size) {
|
|
63
|
+
memcpy(&val, regs + offset, width);
|
|
64
|
+
} else {
|
|
65
|
+
free(regs);
|
|
66
|
+
return LONG2NUM(-1);
|
|
67
|
+
}
|
|
68
|
+
free(regs);
|
|
69
|
+
if (width == sizeof(val.val32)) {
|
|
70
|
+
return LONG2NUM(val.val32);
|
|
71
|
+
} else if (width == sizeof(val.val64)) {
|
|
72
|
+
return LONG2NUM(val.val64);
|
|
73
|
+
} else {
|
|
74
|
+
assert(!"Unreachable");
|
|
75
|
+
return LONG2NUM(-1);
|
|
76
|
+
}
|
|
23
77
|
}
|
|
24
78
|
|
|
25
79
|
static VALUE
|
|
@@ -50,9 +104,44 @@ ptrace_traceme_and_stop(VALUE mod) {
|
|
|
50
104
|
return Qnil;
|
|
51
105
|
}
|
|
52
106
|
|
|
107
|
+
static VALUE
|
|
108
|
+
ptrace_attach_and_wait(VALUE _mod, VALUE pid) {
|
|
109
|
+
long val = ptrace(PTRACE_ATTACH, NUM2LONG(pid), 0, 0);
|
|
110
|
+
if(val < 0)
|
|
111
|
+
rb_sys_fail("ptrace attach failed");
|
|
112
|
+
waitpid(NUM2LONG(pid), NULL, 0);
|
|
113
|
+
return Qnil;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static VALUE
|
|
117
|
+
ptrace_seccomp_get_filter(VALUE _mod, VALUE pid, VALUE index) {
|
|
118
|
+
long count = ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), NULL);
|
|
119
|
+
struct sock_filter *filter;
|
|
120
|
+
VALUE result;
|
|
121
|
+
if(count < 0)
|
|
122
|
+
rb_sys_fail("ptrace seccomp_get_filter failed");
|
|
123
|
+
filter = ALLOC_N(struct sock_filter, count);
|
|
124
|
+
if(ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), filter) != count) {
|
|
125
|
+
xfree(filter);
|
|
126
|
+
rb_sys_fail("ptrace seccomp_get_filter failed");
|
|
127
|
+
}
|
|
128
|
+
result = rb_str_new((const char *)filter, sizeof(struct sock_filter) * count);
|
|
129
|
+
xfree(filter);
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static VALUE
|
|
134
|
+
ptrace_detach(VALUE _mod, VALUE pid) {
|
|
135
|
+
long val = ptrace(PTRACE_DETACH, NUM2LONG(pid), 0, 0);
|
|
136
|
+
if(val < 0)
|
|
137
|
+
rb_sys_fail(0);
|
|
138
|
+
return Qnil;
|
|
139
|
+
}
|
|
140
|
+
|
|
53
141
|
|
|
54
142
|
void Init_ptrace(void) {
|
|
55
143
|
VALUE mSeccompTools = rb_define_module("SeccompTools");
|
|
144
|
+
/* The module to wrap ptrace syscall */
|
|
56
145
|
VALUE mPtrace = rb_define_module_under(mSeccompTools, "Ptrace");
|
|
57
146
|
|
|
58
147
|
/* consts */
|
|
@@ -64,13 +153,26 @@ void Init_ptrace(void) {
|
|
|
64
153
|
rb_define_const(mPtrace, "O_TRACESYSGOOD", UINT2NUM(PTRACE_O_TRACESYSGOOD));
|
|
65
154
|
rb_define_const(mPtrace, "O_TRACEVFORK", UINT2NUM(PTRACE_O_TRACEVFORK));
|
|
66
155
|
|
|
67
|
-
/*
|
|
156
|
+
/* geteventmsg */
|
|
68
157
|
rb_define_module_function(mPtrace, "geteventmsg", ptrace_geteventmsg, 1);
|
|
158
|
+
/* get data */
|
|
69
159
|
rb_define_module_function(mPtrace, "peekdata", ptrace_peekdata, 3);
|
|
70
|
-
|
|
160
|
+
/* get registers */
|
|
161
|
+
rb_define_module_function(mPtrace, "peekuser", ptrace_peekuser, 4);
|
|
162
|
+
/* set ptrace options */
|
|
71
163
|
rb_define_module_function(mPtrace, "setoptions", ptrace_setoptions, 3);
|
|
164
|
+
/* wait for syscall */
|
|
72
165
|
rb_define_module_function(mPtrace, "syscall", ptrace_syscall, 3);
|
|
166
|
+
/* wait for its parent to attach */
|
|
73
167
|
rb_define_module_function(mPtrace, "traceme", ptrace_traceme, 0);
|
|
168
|
+
/* stop itself before parent attaching */
|
|
74
169
|
rb_define_module_function(mPtrace, "traceme_and_stop", ptrace_traceme_and_stop, 0);
|
|
170
|
+
/* attach to an existing process */
|
|
171
|
+
rb_define_module_function(mPtrace, "attach_and_wait", ptrace_attach_and_wait, 1);
|
|
172
|
+
/* retrieve seccomp filter */
|
|
173
|
+
rb_define_module_function(mPtrace, "seccomp_get_filter", ptrace_seccomp_get_filter, 2);
|
|
174
|
+
/* detach from an existing process */
|
|
175
|
+
rb_define_module_function(mPtrace, "detach", ptrace_detach, 1);
|
|
75
176
|
}
|
|
76
177
|
|
|
178
|
+
#endif /* __linux__ */
|
data/lib/seccomp-tools.rb
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# @author david942j
|
|
2
4
|
|
|
3
5
|
# Main module.
|
|
4
6
|
module SeccompTools
|
|
5
7
|
end
|
|
6
8
|
|
|
9
|
+
require 'seccomp-tools/asm/asm'
|
|
10
|
+
require 'seccomp-tools/disasm/disasm'
|
|
7
11
|
require 'seccomp-tools/dumper'
|
|
12
|
+
require 'seccomp-tools/emulator'
|
|
8
13
|
require 'seccomp-tools/version'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'seccomp-tools/asm/compiler'
|
|
2
4
|
require 'seccomp-tools/util'
|
|
3
5
|
|
|
@@ -8,10 +10,11 @@ module SeccompTools
|
|
|
8
10
|
|
|
9
11
|
# Assembler of seccomp bpf.
|
|
10
12
|
# @param [String] str
|
|
13
|
+
# @param [:amd64, :i386] arch
|
|
11
14
|
# @return [String]
|
|
12
15
|
# Raw bpf bytes.
|
|
13
16
|
# @example
|
|
14
|
-
# asm(
|
|
17
|
+
# SeccompTools::Asm.asm(<<-EOS)
|
|
15
18
|
# # lines start with '#' are comments
|
|
16
19
|
# A = sys_number # here's a comment, too
|
|
17
20
|
# A >= 0x40000000 ? dead : next # 'next' is a keyword, denote the next instruction
|
|
@@ -25,7 +28,7 @@ module SeccompTools
|
|
|
25
28
|
# EOS
|
|
26
29
|
# #=> <raw binary bytes>
|
|
27
30
|
def asm(str, arch: nil)
|
|
28
|
-
arch = Util.system_arch if arch.nil?
|
|
31
|
+
arch = Util.system_arch if arch.nil?
|
|
29
32
|
compiler = Compiler.new(arch)
|
|
30
33
|
str.lines.each { |l| compiler.process(l) }
|
|
31
34
|
compiler.compile!.map(&:asm).join
|