Skip to content

Commit

Permalink
Merge pull request #42 from cruise-automation/collin/checksec
Browse files Browse the repository at this point in the history
checksec wrapper
  • Loading branch information
Collin Mulliner committed Aug 17, 2020
2 parents 3e2b225 + e6b3808 commit 4f656a8
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 1 deletion.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Always update Version in Makefile
## Unreleased

### Added
- checksec wrapper script, see [check_sec.sh](scripts/check_sec.sh) and [Checksec Wrapper Readme](Checksec.md)
- link support for extfs, this requires `https://github.com/crmulliner/e2tools/tree/link_support` (or later)

### Changed
Expand Down
85 changes: 85 additions & 0 deletions Checksec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# checksec Integration

[checksec](https://github.com/slimm609/checksec.sh) is a bash script for checking security properties of executables (like PIE, RELRO, Canaries, ...).

Checksec is an incredible helpful tool therefore we developed a wrapper script for FwAnalyzer to ease the usage of checksec. Below
we go through the steps required to use checksec with FwAnalyzer.

## Installation

The installation is rather simple. Clone the checksec repository and copy the `checksec` script to a directory in your PATH
or add the directory containing `checksec` to your PATH.

## Configuration

Configuration is done in two steps. First step is adding a `FileContent` check that uses the `Script` option.
The second step is creating the checksec wrapper configuration. The configuration allows you to selectively skip files
(e.g. vendor binaries) and fine tune the security features that you want to enforce.

### checksec wrapper configuration

The checksec wrapper has two options, and uses JSON:

- cfg : checksec config, where you can select acceptable values for each field in the checksec output. The key is the name of the checksec field and the value is an array where each item is an acceptable value (e.g. allow `full` and `partial` RELRO). Omitted fields are not checked.
- skip : array of fully qualified filenames that should be not checked

example config:
```json
{
"cfg":
{
"pie": ["yes"],
"nx": ["yes"],
"relo": ["full", "partial"]
},
"skip": ["/usr/bin/bla","/bin/blabla"]
}
```

### FwAnalyzer configuration

The FwAnalyzer configuration uses the checksec wrapper config and looks like in the example below.
We define a `FileContent` check and select `/usr/bin` as the target directory.
The name of the wrapper script is `check_sec.sh`.
We pass two options to the script. First argument `*` selects all files in `/usr/bin` and
the second argument is the checksec wrapper config we created above.

example config:
```ini
[FileContent."checksec_usr_bin"]
File = "/usr/bin"
Script = "check_sec.sh"
ScriptOptions = ["*",
"""
{
"cfg":{
"pie": ["yes"],
"nx": ["yes"],
"relo": ["full", "partial"]
},
"skip": ["/usr/bin/bla","/bin/blabla"]
}
"""]
```


### Example Output

```json
"offenders": {
"/usr/bin/example": [
{
"canary": "no",
"fortified": "0",
"fortify-able": "24",
"fortify_source": "no",
"nx": "yes",
"pie": "no",
"relro": "partial",
"rpath": "no",
"runpath": "no",
"symbols": "no"
}
]
}
```
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ It also includes general configuration files that can be included in target spec

Check.py in the [devices/](devices) folder provides a universal script to effectively use FwAnalyzer, see [devices/Readme.md](devices/Readme.md) for details. This likely is how most people will invoke FwAnalyzer.

The [scripts/](scripts/) folder contains helper scripts that can be called from FwAnalyzer for file content analysis and data extraction.
The [scripts/](scripts/) folder contains helper scripts that can be called from FwAnalyzer for file content analysis and data extraction. Most interesting should be our checksec wrapper [check_sec.sh](scripts/check_sc.sh), see the [Checksec Wrapper Readme](Checksec.md).

## Config Options

Expand Down
72 changes: 72 additions & 0 deletions scripts/check_sec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash

FILEPATH=$1
ORIG_FILENAME=$2
ORIG_UID=$3
ORIG_GID=$4
ORIG_MODE=$5
ORIG_LABEL=$6
CONFIG=$8

RESULT=$(checksec --output=json --file="$1")

export RESULT
export FILEPATH
export CONFIG
export ORIG_FILENAME

# Config format is JSON
# array for values allows multiple acceptable values
# {"cfg":
# {
# "pie": ["yes"],
# "relo": ["full", "partial"]
# },
# "skip": ["/usr/bin/bla"]
# }
#
# usable cfg fields, omitted fields are not checked:
# {
# "canary": "no",
# "fortify_source": "no",
# "nx": "yes",
# "pie": "no",
# "relro": "partial",
# "rpath": "no",
# "runpath": "no",
# "symbols": "no"
# }


python -c 'import json
import sys
import os
cfg = os.getenv("CONFIG")
res = os.getenv("RESULT")
fp = os.getenv("FILEPATH")
orig_name = os.getenv("ORIG_FILENAME")
try:
expected = json.loads(cfg.rstrip())
result = json.loads(res.rstrip())
if "skip" in expected:
if orig_name in expected["skip"]:
sys.exit(0)
for k in expected["cfg"]:
if k in result[fp]:
passed = False
for expected_value in expected["cfg"][k]:
if expected_value == result[fp][k]:
passed = True
break
if not passed:
print(json.dumps(result[fp]).rstrip())
sys.exit(0)
except Exception as e:
pass
sys.exit(0)
'

0 comments on commit 4f656a8

Please sign in to comment.