Skip to content

Commit

Permalink
checkers: README: Add signature finding quickstart
Browse files Browse the repository at this point in the history
Signed-off-by: John Andersen <johnandersenpdx@gmail.com>
  • Loading branch information
pdxjohnny committed Jan 11, 2021
1 parent 1a49132 commit bb6e115
Showing 1 changed file with 108 additions and 0 deletions.
108 changes: 108 additions & 0 deletions cve_bin_tool/checkers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,114 @@ You can find these by-
$ strings (path of the binary) | grep -i (product_name)
```

### Quickstart for finding patterns

What often helps is trying to find an `.rpm` (or more than one) or a package
which contains the product you're looking for.

Searching on https://pkgs.org is a good place to start.

For this example we'll be using `libvorbis`: https://pkgs.org/search/?q=libvorbis

In the below example we picked fedora 33's package for version 1.3.7 of
libvorbis. We can extract the `.rpm` file using a combintation of
[rpm2cpio and cpio](https://www.cyberciti.biz/tips/how-to-extract-an-rpm-package-without-installing-it.html)
or using [rpmfile](https://pypi.org/project/rpmfile/). Sometimes you'll have
packages which come in `.deb` or .`tar` files.

- `.deb` files can be extracted with `ar x somefile.deb && tar xvf data.tar.xz`

- `.tar` files can be extrated using `tar`

```console
$ curl -sfL 'https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/33/Everything/x86_64/os/Packages/l/libvorbis-1.3.7-2.fc33.x86_64.rpm' | rpmfile -xv -
/tmp/tmp.U3wkntEqtD/usr/lib/.build-id/02/980384bc359497f0121fc74974e465ba7e29aa
/tmp/tmp.U3wkntEqtD/usr/lib/.build-id/1c/ff0ed918467a6224a5108793bf779e61486151
/tmp/tmp.U3wkntEqtD/usr/lib/.build-id/75/8407ea857c63ae42c4d9959ad252de6fb9bcca
/tmp/tmp.U3wkntEqtD/usr/lib64/libvorbis.so.0
/tmp/tmp.U3wkntEqtD/usr/lib64/libvorbis.so.0.4.9
/tmp/tmp.U3wkntEqtD/usr/lib64/libvorbisenc.so.2
/tmp/tmp.U3wkntEqtD/usr/lib64/libvorbisenc.so.2.0.12
/tmp/tmp.U3wkntEqtD/usr/lib64/libvorbisfile.so.3
/tmp/tmp.U3wkntEqtD/usr/lib64/libvorbisfile.so.3.3.8
/tmp/tmp.U3wkntEqtD/usr/share/doc/libvorbis/AUTHORS
/tmp/tmp.U3wkntEqtD/usr/share/licenses/libvorbis/COPYING
```

Then look for which files you downloaded are binaries or libraries. We can use
the `file` command combined with the `find` command for this. The `find`
command will list every file in the directory we proivde to it (`.` in this
case) and execute any program we want using that filename. In this case we want
to run the `file` command on each file we get from `find`.

We want to filter the output using `grep` to show us only executables (programs
you run) and shared objects (libaries programs use) using
`-E 'executable,|shared object,'` which is a regex which says to show lines that
`find` output if they have either `executable,` or `shared object,` in them.

The final `tee` command in combination with `sed` is creating a new file called
`executables.txt` which has all the filenames in it. It does this by only
writing what comes before the `:` to the file that was in the output of the
`grep` command which looked for executables.

```console
$ find . -exec file {} \; | grep -E 'executable,|shared object,' | tee >(sed -e 's/:.*//g' > executables.txt)
./usr/lib64/libvorbisfile.so.3.3.8: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=1cff0ed918467a6224a5108793bf779e61486151, stripped
./usr/lib64/libvorbisenc.so.2.0.12: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=02980384bc359497f0121fc74974e465ba7e29aa, stripped
./usr/lib64/libvorbis.so.0.4.9: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=758407ea857c63ae42c4d9959ad252de6fb9bcca, stripped
```

You'll want to run strings on those binaries and do a case insensitive search
for the package name using `grep -i`.

```console
$ strings $(cat executables.txt) | sort | uniq | grep -i libvorbis
3?Xiph.Org libVorbis 1.3.7
libvorbisenc.so.2
libvorbisenc.so.2.0.12-1.3.7-2.fc33.x86_64.debug
libvorbisfile.so.3
libvorbisfile.so.3.3.8-1.3.7-2.fc33.x86_64.debug
libvorbis.so.0
libvorbis.so.0.4.9-1.3.7-2.fc33.x86_64.debug
Xiph.Org libVorbis I 20200704 (Reducing Environment)
```

You also my want to look for the version number. In this case it's `1.3.7`.

```console
$ strings $(cat executables.txt) | sort | uniq | grep -i 1.3.7
3?Xiph.Org libVorbis 1.3.7
libvorbisenc.so.2.0.12-1.3.7-2.fc33.x86_64.debug
libvorbisfile.so.3.3.8-1.3.7-2.fc33.x86_64.debug
libvorbis.so.0.4.9-1.3.7-2.fc33.x86_64.debug
```

In this case the most interesting line in the output of the above two commands
is `3?Xiph.Org libVorbis 1.3.7`. We can probably use this to create a regex for
`VERSION_PATTERS`.

That regex would might like this: `3\?Xiph.Org libVorbis ([0-9]+\.[0-9]+\.[0-9]+)`

> If you can't get a signature match using just regex you may end up needing to
> overwrite the
> [`get_version()`](https://github.com/intel/cve-bin-tool/blob/master/cve_bin_tool/checkers/__init__.py#L120-L132)
> method for the checker, but that should be a last resort if you can't find a
> regex that works for `VERSION_PATTERNS`.
>
> A note about this example:
> In the case of libvorbis the versions containing
> [CVEs](https://www.cvedetails.com/product/11738/Libvorbis-Libvorbis.html?vendor_id=6970)
> are 1.2.0 and below. The `.rpm` we used for this example was from version
> 1.3.7. While this was a nice example for how one might find a signature, it
> in the end is not all the work that is needed to create a checker for
> libvorbis. We need to make sure that any checker we develop has a
> `get_version()` function which works for versions of the software which have
> CVEs. If not overridden in a subclass the Checker base class implements a
> `get_version()` method which will use regex to determine the version (as
> described above). In the case of libvorbis a custom `get_version()` function
> is likely needed, this is because the signature we found is not in the 1.2.0
> version, where the CVE is found.
### Finding Vendor Product pairs

Every checker class must contain the vendor and product name pair(s)
Expand Down

0 comments on commit bb6e115

Please sign in to comment.