Skip to content

Commit 8a1b01f

Browse files
author
etke
committed
Re-work CLI using clap derive
Based on PR #28 by cgzones
1 parent 3d5a0fe commit 8a1b01f

17 files changed

+985
-604
lines changed

Cargo.lock

+52-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+9-5
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ repository = "https://github.com/etke/checksec.rs"
1919
version = "0.0.9"
2020

2121
[profile.release]
22-
codegen-units = 1 # Reduce number of codegen units to increase optimizations
23-
lto = true # Enable Link Time Optimization
24-
opt-level = 'z' # Optimize for size
25-
panic = 'abort' # Abort on panic
22+
codegen-units = 1 # Reduce number of codegen units to increase optimizations
23+
lto = true # Enable Link Time Optimization
24+
opt-level = 'z' # Optimize for size
25+
panic = 'abort' # Abort on panic
26+
strip = 'debuginfo' # Strip debuginfo
27+
rpath = false # Disable RPATH
28+
debug = false # No debug info at all
2629

2730
[dependencies]
28-
clap = {version = "4.0.14", features = ["cargo"]}
31+
clap = {version = "4.0.14", features = ["cargo", "derive"]}
2932
colored = {version = "2.0.0", optional = true}
3033
colored_json = {version = "3.0.1", optional = true}
3134
goblin = "0.6.0"
@@ -64,6 +67,7 @@ path = "src/main.rs"
6467
color = ["colored", "colored_json", "xattr"]
6568
default = ["elf", "macho", "pe", "color", "maps"]
6669
elf = ["shared"]
70+
helpers = []
6771
macho = ["shared"]
6872
maps = []
6973
pe = []

README.md

+155-27
Original file line numberDiff line numberDiff line change
@@ -49,60 +49,188 @@ For instances where you want to compile for a different target OS or architectur
4949

5050
## Usage
5151

52+
**Note:** command line args/options have changed as of version `0.1.0`
53+
54+
```sh
55+
$ checksec
56+
Fast multi-platform (ELF/PE/MachO) binary checksec command line utility and library.
57+
58+
Usage: checksec <COMMAND> [OPTIONS]
59+
60+
Commands:
61+
blob Scan binaries or compressed archives by path
62+
process Scan binaries by process
63+
help Print this message or the help of the given subcommand(s)
64+
65+
Options:
66+
--no-color Disables color output
67+
--format <FORMAT> Output format [default: text] [possible values: text, json, json-pretty]
68+
-h, --help Print help information
69+
-V, --version Print version information
70+
```
71+
72+
## Subcommands usage
73+
74+
### blob
75+
76+
```sh
77+
$ checksec blob
78+
Scan binaries or compressed archives by path
79+
80+
Usage: checksec blob [OPTIONS] [PATHS]
81+
command | checksec blob [OPTIONS] --stdin
82+
83+
Arguments:
84+
[PATHS]...
85+
86+
Options:
87+
-s, --stdin Read paths from stdin
88+
--no-color Disables color output
89+
--format <FORMAT> Output format [default: text] [possible values: text, json, json-pretty]
90+
-h, --help Print help information
91+
```
92+
93+
### process
94+
95+
```sh
96+
$ checksec process
97+
Scan binaries by process
98+
99+
Usage: checksec process <command> [OPTIONS]
100+
101+
Commands:
102+
all Scan all running processes
103+
id Scan processes by PID
104+
name Scan processes by name
105+
help Print this message or the help of the given subcommand(s)
106+
107+
Options:
108+
--no-color Disables color output
109+
--format <FORMAT> Output format [default: text] [possible values: text, json, json-pretty]
110+
-h, --help Print help information
111+
```
112+
113+
#### process all
114+
52115
```sh
53-
USAGE:
54-
checksec [FLAGS] [OPTIONS]
116+
$ checksec process all -h
117+
Scan all running processes
55118

56-
FLAGS:
57-
-h, --help Prints help information
58-
-j, --json Output in json format
59-
--pretty Human readable json output
60-
-P, --process-all Check all running processes
61-
-V, --version Prints version information
119+
Usage: checksec process all [OPTIONS]
62120

63-
OPTIONS:
64-
-d, --directory <DIRECTORY> Target directory
65-
-f, --file <FILE> Target file
66-
-p, --process <NAME> Name of running process to check
121+
Options:
122+
-m, --maps Include process memory maps (linux/windows only)
123+
--no-color Disables color output
124+
--format <FORMAT> Output format [default: text] [possible values: text, json, json-pretty]
125+
-h, --help Print help information
67126
```
68127

69-
### Example
128+
#### process id
129+
130+
```sh
131+
$ checksec process id
132+
Scan processes by PID
133+
134+
Usage: checksec process id [OPTIONS] <PIDS>
135+
command | checksec process id [OPTIONS] --stdin
136+
137+
Arguments:
138+
[PIDS]...
139+
140+
Options:
141+
-m, --maps Include process memory maps (linux/windows only)
142+
-s, --stdin Read process ids from stdin
143+
--no-color Disables color output
144+
--format <FORMAT> Output format [default: text] [possible values: text, json, json-pretty]
145+
-h, --help Print help information
146+
```
147+
148+
### Examples
70149

71150
#### standalone checksec
72151

73-
##### individual binary
152+
##### individual blob (binary/compressed archive)
74153

75154
```sh
76-
$ checksec -f test/binaries/true-x86_64
77-
ELF64: | Canary: true CFI: false SafeStack: false Fortify: true Fortified: 2 NX: true PIE: None Relro: Partial RPATH: None RUNPATH: None | File: test/binaries/true-x86_64
155+
$ checksec blob test/binaries/true-x86_64
156+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 2 Fortifiable: 2 NX: true PIE: None Relro: Partial RPATH: None RUNPATH: None | File: test/binaries/true-x86_64
157+
# or from stdin
158+
$ echo "test/binaries/true-x86_64" | checksec blob --stdin
159+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 2 Fortifiable: 2 NX: true PIE: None Relro: Partial RPATH: None RUNPATH: None | File: test/binaries/true-x86_64
78160
```
79161

80-
##### individual binary (json output)
162+
##### individual blob (binary/compressed archive) (JSON output)
81163

82164
```sh
83-
$ checksec -f test/binaries/true-x86_64 --json
84-
{"binaries":[{"binarytype":"Elf64","file":"test/binaries/true-x86_64","properties":{"Elf":{"canary":true,"clang_cfi":false,"clang_safestack":false,"fortified":2,"fortify":true,"nx":true,"pie":"None","relro":"Partial","rpath":{"paths":["None"]},"runpath":{"paths":["None"]}}}}]}
165+
$ checksec blob --format json test/binaries/true-x86_64
166+
{"binaries":[{"binarytype":"Elf64","file":"test/binaries/true-x86_64","properties":{"Elf":{"canary":true,"clang_cfi":false,"clang_safestack":false,"fortifiable":2,"fortified":2,"fortify":"Partial","nx":true,"pie":"None","relro":"Partial","rpath":{"paths":["None"]},"runpath":{"paths":["None"]}}}}]}
167+
```
168+
169+
##### multiple blobs via stdin
170+
171+
```sh
172+
# newline delminated
173+
$ dpkg -L dpkg | target/release/checksec blob --stdin 2>/dev/null
174+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 9 Fortifiable: 3 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /sbin/start-stop-daemon
175+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 10 Fortifiable: 8 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/dpkg
176+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 9 Fortifiable: 5 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/dpkg-deb
177+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 9 Fortifiable: 6 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/dpkg-divert
178+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 9 Fortifiable: 7 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/dpkg-query
179+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 5 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/dpkg-split
180+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 5 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/dpkg-statoverride
181+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 9 Fortifiable: 5 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/dpkg-trigger
182+
ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 5 Fortifiable: 3 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/update-alternatives
85183
```
86184

87185
##### running processes
88186

89187
```sh
90-
$ checksec -P
91-
-zsh(34)
92-
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: true Fortified: 8 NX: true PIE: Full Relro: Full RPATH: None RUNPATH: None | File: /bin/zsh
188+
$ checksec process all
189+
zsh(34)
190+
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 19 NX: true PIE: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/zsh
93191
checksec(216)
94-
↪ ELF64: | Canary: false CFI: false SafeStack: false Fortify: false Fortified: 0 NX: true PIE: Full Relro: Full RPATH: None RUNPATH: None | File: /home/etke/.cargo/bin/checksec
95-
init(1)
96-
↪ ELF64: | Canary: false CFI: false SafeStack: false Fortify: false Fortified: 0 NX: true PIE: None Relro: Partial RPATH: None RUNPATH: None | File: /init
192+
↪ ELF64: | Canary: false CFI: false SafeStack: false Fortify: None Fortified: 0 Fortifiable: 8 NX: true PIE: Full Relro: Full RPATH: None RUNPATH: None | File: /home/etke/.cargo/bin/checksec
97193
```
98194

99-
##### running processes (json output)
195+
##### running processes (JSON output)
100196

101197
```sh
102-
$ checksec -P --json
198+
$ checksec process all --format json
103199
{"processes":[{"binary":[{"binarytype":"Elf64","file":"/bin/zsh","properties":{"Elf":{"canary":true,"clang_cfi":false,"clang_safestack":false,"fortified":8,"fortify":true,"nx":true,"pie":"PIE","relro":"Full","rpath":{"paths":["None"]},"runpath":{"paths":["None"]}}}}],"pid":34},{"binary":[{"binarytype":"Elf64","file":"/init","properties":{"Elf":{"canary":false,"clang_cfi":false,"clang_safestack":false,"fortified":0,"fortify":false,"nx":true,"pie":"None","relro":"Partial","rpath":{"paths":["None"]},"runpath":{"paths":["None"]}}}}],"pid":1},{"binary":[{"binarytype":"Elf64","file":"/home/etke/.cargo/bin/checksec","properties":{"Elf":{"canary":false,"clang_cfi":false,"clang_safestack":false,"fortified":0,"fortify":false,"nx":true,"pie":"PIE","relro":"Full","rpath":{"paths":["None"]},"runpath":{"paths":["None"]}}}}],"pid":232}]}
104200
```
105201

202+
##### running processes with name(s)
203+
204+
```sh
205+
$ checksec process name zsh
206+
zsh(34)
207+
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 19 NX: true PIE: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/zsh
208+
# or from stdin (space delimited)
209+
$ echo "zsh vim" | checksec process name --stdin
210+
# or from stdin (newline delimited)
211+
$ printf "zsh\vim" | checksec process name --stdin
212+
vim(4567)
213+
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 10 Fortifiable: 18 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/vim
214+
zsh(1234)
215+
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 19 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/zsh
216+
```
217+
218+
##### running process by id(s)
219+
220+
```sh
221+
$ checksec process id 1234
222+
zsh(1234)
223+
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 19 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/zsh
224+
# or from stdin (space delimited)
225+
$ pidof zsh | checksec process id --stdin
226+
# or from stdin (newline delimited)
227+
$ pgrep zsh | checksec process id --stdin
228+
zsh(4567)
229+
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 19 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/zsh
230+
zsh(1234)
231+
↪ ELF64: | Canary: true CFI: false SafeStack: false Fortify: Partial Fortified: 8 Fortifiable: 19 NX: true Pie: Full Relro: Full RPATH: None RUNPATH: None | File: /usr/bin/zsh
232+
```
233+
106234
#### libchecksec
107235

108236
Just add the following to any current project with goblin dependencies to enable checksec trait on `goblin::Object::{Elf, Mach, PE}` objects.

examples/elf_print_checksec_results.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() {
1212
if let Ok(buf) = fs::read(&argv[1]) {
1313
match Object::parse(&buf).unwrap() {
1414
Object::Elf(elf) => {
15-
println!("{:#?}", CheckSecResults::parse(&elf))
15+
println!("{:#?}", CheckSecResults::parse(&elf));
1616
}
1717
_ => println!("Not an elf binary."),
1818
}

examples/macho_print_checksec_results.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ fn parse(bytes: &[u8]) {
3838
mach.header.cpusubtype(),
3939
)
4040
.unwrap_or("UNKNOWN");
41-
println!("# Machine type {}:", machine);
42-
println!("{:#?}", CheckSecResults::parse(&mach))
41+
println!("# Machine type {machine}:");
42+
println!("{:#?}", CheckSecResults::parse(&mach));
4343
}
4444
Archive(archive) => {
4545
let fatarch = fatarch.unwrap();
@@ -50,16 +50,12 @@ fn parse(bytes: &[u8]) {
5050
for member in archive.members() {
5151
match archive.extract(member, archive_bytes) {
5252
Ok(ext_bytes) => {
53-
println!(
54-
"# Archive member {}:",
55-
member
56-
);
53+
println!("# Archive member {member}:",);
5754
parse(ext_bytes);
5855
}
5956
Err(err) => {
6057
eprintln!(
61-
"Failed to extract member {}: {}",
62-
member, err
58+
"Failed to extract member {member}: {err}",
6359
);
6460
}
6561
}

0 commit comments

Comments
 (0)