attackmap-analyzer-cpp 0.2.0__py3-none-any.whl
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.
- attackmap_analyzer_cpp/__init__.py +3 -0
- attackmap_analyzer_cpp/analyzer.py +601 -0
- attackmap_analyzer_cpp/framework_routes.py +255 -0
- attackmap_analyzer_cpp/native_deps.py +524 -0
- attackmap_analyzer_cpp/native_sinks.py +1737 -0
- attackmap_analyzer_cpp-0.2.0.dist-info/METADATA +170 -0
- attackmap_analyzer_cpp-0.2.0.dist-info/RECORD +11 -0
- attackmap_analyzer_cpp-0.2.0.dist-info/WHEEL +5 -0
- attackmap_analyzer_cpp-0.2.0.dist-info/entry_points.txt +2 -0
- attackmap_analyzer_cpp-0.2.0.dist-info/licenses/LICENSE +21 -0
- attackmap_analyzer_cpp-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: attackmap-analyzer-cpp
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: C++ ecosystem analyzer plugin for AttackMap (Crow, Pistache, Drogon, cpprestsdk; libcurl/cpr; OpenSSL/Botan/libsodium/Crypto++; libpqxx/mongocxx/redis-plus-plus).
|
|
5
|
+
Author: AttackMap Contributors
|
|
6
|
+
Author-email: Matthew Davis <mlaify@mlaify.io>
|
|
7
|
+
Maintainer-email: Matthew Davis <mlaify@mlaify.io>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/mlaify/attackmap-analyzer-cpp
|
|
10
|
+
Project-URL: Repository, https://github.com/mlaify/attackmap-analyzer-cpp
|
|
11
|
+
Project-URL: Issues, https://github.com/mlaify/attackmap-analyzer-cpp/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/mlaify/attackmap-analyzer-cpp/blob/main/CHANGELOG.md
|
|
13
|
+
Project-URL: AttackMap core, https://github.com/mlaify/AttackMap
|
|
14
|
+
Keywords: security,static-analysis,appsec,defensive-security,attackmap,attackmap-plugin
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Intended Audience :: Information Technology
|
|
18
|
+
Classifier: Intended Audience :: System Administrators
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
25
|
+
Classifier: Topic :: Security
|
|
26
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.11
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: pydantic>=2.7.0
|
|
32
|
+
Provides-Extra: core
|
|
33
|
+
Requires-Dist: attackmap>=0.6.0; extra == "core"
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: build>=1.2.0; extra == "dev"
|
|
37
|
+
Requires-Dist: attackmap>=0.6.0; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# attackmap-analyzer-cpp
|
|
41
|
+
|
|
42
|
+
> [!IMPORTANT]
|
|
43
|
+
> **Active development, slow pace.** AttackMap is under active development, but
|
|
44
|
+
> progress may be slow until more contributors or co-maintainers join. Help is
|
|
45
|
+
> very welcome with the core engine, an analyzer, the macOS app, or the docs —
|
|
46
|
+
> see [CONTRIBUTING.md](CONTRIBUTING.md) or open an issue on
|
|
47
|
+
> [mlaify/AttackMap](https://github.com/mlaify/AttackMap/issues) to say hello.
|
|
48
|
+
> Security reports are still welcome at [security@mlaify.io](mailto:security@mlaify.io).
|
|
49
|
+
|
|
50
|
+
C++ ecosystem analyzer for [AttackMap](https://github.com/mlaify/AttackMap).
|
|
51
|
+
|
|
52
|
+
This analyzer extracts structured signals from C++ source trees (`.cpp`, `.cc`, `.cxx`, `.hpp`, `.hxx`, `.ipp`, `.tpp`):
|
|
53
|
+
|
|
54
|
+
- **Web frameworks** — Crow (`CROW_ROUTE` macro with `.methods("POST"_method, ...)` chain), Pistache (`Routes::Get/Post/...`), Drogon (`registerHandler` with explicit method list, `ADD_METHOD_TO`, `METHOD_ADD` relative to the controller's `/namespace/Class` path, and `PATH_ADD`), cpprestsdk / Casablanca (`http_listener("https://...")` URL extraction), cpp-httplib (`svr.Get/Post/Put/Patch/Delete/Options` on a declared `httplib::Server`/`SSLServer`, regex paths kept as written), oat++ (`ENDPOINT`/`ENDPOINT_ASYNC`; an `AUTHORIZATION(...)` parameter sets `Route.auth = required`), restbed (`set_path`/`set_paths` on a `Resource` joined with its `set_method_handler` methods; `set_authentication_handler` on the resource or service sets `Route.auth = required`)
|
|
55
|
+
- **HTTP clients (external calls)** — libcurl (`CURLOPT_URL` literals), cpr (`cpr::Get(cpr::Url{"..."})`, `cpr::Post(...)`), cpprestsdk (`web::http::client::http_client(URL)`)
|
|
56
|
+
- **Databases** — libpqxx (`pqxx::connection`, `pqxx::work`), MySQL X DevAPI (`mysqlx::Session`), mongocxx (`mongocxx::client` + `mongocxx::uri`), redis-plus-plus (`sw::redis::Redis`), SOCI (`soci::session`), sqlite_orm (`sqlite_orm::make_storage`)
|
|
57
|
+
- **Auth/crypto** — OpenSSL (TLS / EVP / RAND), Botan (`TLS::Server`, `Cipher_Mode`, `PKCS5_PBKDF2`, `Scrypt`), libsodium (`crypto_pwhash` → argon2, `crypto_secretbox`, AEAD primitives), Crypto++ (`CryptoPP::AES`, `CryptoPP::SHA256`, `CryptoPP::Argon2`, `CryptoPP::HMAC`), JWT C++ libraries (`jwt::create`, `jwt::decode`, `jwt::verify`)
|
|
58
|
+
- **Secrets** — `std::getenv`, `getenv` with secret-shaped names
|
|
59
|
+
- **Service hints** — project name from `CMakeLists.txt` `project(NAME ...)` declaration
|
|
60
|
+
- **Dependencies (SBOM)** — vcpkg (`vcpkg.json`), Conan (`conanfile.txt`, `conanfile.py`, `conan.lock`) and CMake (`FetchContent_Declare`, `ExternalProject_Add`, `CPMAddPackage`, `find_package`), so `--cve` reaches native dependencies; unpinned CMake downloads are reported as supply-chain issues (see [Dependencies](#dependencies))
|
|
61
|
+
- **Memory-safety and command-exec sinks** — unbounded copies, non-constant printf formats, `system`/`popen`/`exec*`, input-controlled `memcpy` lengths and allocation-size overflows, tied to request and input sources in the same function (see [Native sinks](#native-sinks))
|
|
62
|
+
|
|
63
|
+
All emissions populate AttackMap's Signal v2 fields (line numbers + evidence snippets + confidence) so downstream insights can cite `path/to/file.cpp:NN`.
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
uv tool install attackmap --with attackmap-analyzer-cpp \
|
|
69
|
+
--index mlaify=https://pkg.mlaify.io/pypi/simple/ --index-strategy first-index
|
|
70
|
+
# or from source:
|
|
71
|
+
pip install git+https://github.com/mlaify/attackmap-analyzer-cpp.git
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The analyzer is registered with AttackMap via the `attackmap.analyzers` entry-point group.
|
|
75
|
+
|
|
76
|
+
## Usage with AttackMap
|
|
77
|
+
|
|
78
|
+
This analyzer is **experimental and opt-in** (`enabled_by_default=False`): installing it does not make it run on every scan. Select it explicitly:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
attackmap analyze /path/to/cpp/repo -m cpp
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Detection
|
|
85
|
+
|
|
86
|
+
`detect()` returns true when any `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hxx`, `.ipp`, or `.tpp` file is present, or `.h` headers in a CMake project that enables CXX (one walk), ignoring `_deps/`, `third_party/`, `external/`, `.cache/`, `Debug/`, `Release/` and AttackMap's shared skip list (`build/`, `out/`, `vendor/`, `node_modules/`, `.git/`, ...). Skip directories are matched only *inside* the repo, so a checkout under e.g. `/build/...` is still scanned. Files are walked with `attackmap.sdk.iter_repo_files`, which does not follow symlinks out of the repo, and read with `read_source`, which falls back to cp1252/latin-1 for legacy-encoded sources.
|
|
87
|
+
|
|
88
|
+
### `.h` ownership
|
|
89
|
+
|
|
90
|
+
`.h` ownership is decided per repo, by the same rule in both the C and C++ analyzers, so exactly one of them analyzes each header whichever of `-m c` / `-m cpp` is selected:
|
|
91
|
+
|
|
92
|
+
- `.h` belongs to **C++** if the repo has any C++ source or header (`.cpp`, `.cc`, `.cxx`, `.hpp`, `.hxx`, `.ipp`, `.tpp`) or a `CMakeLists.txt` that enables CXX (`project(... CXX ...)`, `enable_language(CXX)` or `CMAKE_CXX_STANDARD`). A bare `project(foo)` doesn't count.
|
|
93
|
+
- Otherwise `.h` belongs to **C**.
|
|
94
|
+
- Files under directories either plugin prunes (`build/`, `third_party/`, `Debug/`, `Release/`, ...) are never markers.
|
|
95
|
+
|
|
96
|
+
In a mixed repo, `.c` files go to C, and `.cpp`/`.hpp`/... plus `.h` go to C++. Running only one of the two analyzers on a mixed repo leaves the other's files unanalyzed. It never double-counts them.
|
|
97
|
+
|
|
98
|
+
A repo with only `.c` and `.h` files (and no C++ CMake) is not picked up here.
|
|
99
|
+
|
|
100
|
+
## Dependencies
|
|
101
|
+
|
|
102
|
+
`native_deps.py` emits `DependencyHint`s (mlaify/AttackMap#191). The module is shared verbatim with attackmap-analyzer-c. Core dedupes identical records when both analyzers run.
|
|
103
|
+
|
|
104
|
+
| Source | Ecosystem | Version | `dev` |
|
|
105
|
+
|---|---|---|---|
|
|
106
|
+
| `vcpkg.json` `dependencies` | `vcpkg` | `overrides` pin (`resolved=True`), else `>=` from `version>=`, else empty (the `builtin-baseline` decides; it's recorded in the evidence) | `"host": true` |
|
|
107
|
+
| `conanfile.txt` `[requires]` / `[tool_requires]` / `[build_requires]` / `[test_requires]` | `conan` | as written (`1.2.13`, `[>=1.80 <2.0]`) | tool/build/test sections |
|
|
108
|
+
| `conanfile.py` `requires = ...`, `self.requires("x/1.0")` and the tool/build/test forms (parsed with `ast`, never executed; comments and docstrings don't count) | `conan` | as written | tool/build/test |
|
|
109
|
+
| `conan.lock` (Conan 2 lists and Conan 1.x `graph_lock.nodes`) | `conan` | exact (`resolved=True`) | `build_requires`, build-context nodes |
|
|
110
|
+
| CMake `FetchContent_Declare` / `ExternalProject_Add` / `CPMAddPackage` | `cmake` | `GIT_TAG`, a CPM version, or a version in the archive URL | test/example manifests, test frameworks |
|
|
111
|
+
| CMake `find_package(Name [version] [EXACT])` | `cmake` | `>=version` / `==version`, ranges `1.2...<2.0` → `>=1.2,<2.0` | test/example manifests, test frameworks |
|
|
112
|
+
|
|
113
|
+
`cmake` is inventory-only in core: it has no OSV database, so `--cve` reports those dependencies as not CVE-checked. `conan` and `vcpkg` map to OSV ConanCenter and vcpkg. Build tools and CMake modules (`Threads`, `PkgConfig`, `Python3`, `Git`...) aren't dependencies.
|
|
114
|
+
|
|
115
|
+
**Unpinned downloads** are `SupplyChainIssue(kind="mutable_vcs_dependency")` records:
|
|
116
|
+
|
|
117
|
+
| Download | Severity |
|
|
118
|
+
|---|---|
|
|
119
|
+
| git download with no `GIT_TAG`, or a `GIT_TAG` that names a branch (`main`, `master`, `develop`...) | medium |
|
|
120
|
+
| any other tag or a short SHA | low |
|
|
121
|
+
| a full 40-hex commit SHA | not flagged |
|
|
122
|
+
| `URL` download without `URL_HASH`/`URL_MD5` | medium |
|
|
123
|
+
|
|
124
|
+
Values that are CMake variables (`${X}`) are never flagged. Comments, quoted strings and bracket arguments (`[[ ]]`) never contain commands. Malformed or deeply nested manifests are skipped.
|
|
125
|
+
|
|
126
|
+
## Coverage notes
|
|
127
|
+
|
|
128
|
+
- **Marked experimental**: like the C analyzer, regex coverage of C++ has more false-positive risk than language-specific analyzers with strict imports. Confidence tiering is the primary defense (0.9 for hash-class auth primitives, 0.85 for canonical TLS / cipher / JWT API hits, 0.6 for keyword sweeps).
|
|
129
|
+
- **Crow `.methods("X"_method)` chains**: when present, the route emits one Route per method in the chain. When absent, the route emits with method `ANY`.
|
|
130
|
+
- **Drogon `registerHandler`, `ADD_METHOD_TO`, `METHOD_ADD` and `PATH_ADD`**: all shapes are extracted, including the `{Drogon::Get, Drogon::Post}` initializer-list form and multi-method macros (`Put, Patch, "AuthFilter"`), which produce one Route per method (`ANY` when none is given). `METHOD_ADD` paths are prefixed with the controller's class path, e.g. `api::v1::User` → `/api/v1/User/{id}`.
|
|
131
|
+
- **cpp-httplib / oat++ / restbed routes** (`framework_routes.py`): a `.Get("/x")` call counts only on a receiver declared as a `Server` in the same file, so `httplib::Client` calls aren't routes. Servers from `std::make_unique/make_shared<httplib::Server>` count. Commented-out code and text inside string literals are ignored. A restbed `set_authentication_handler` guards its own `Resource` (even one with a non-literal path), or every resource when called on a declared `Service`; on any other receiver the route's auth stays `unknown`. oat++ and restbed paths are rooted (`users` → `/users`). A router-level prefix (oat++ `addController`, restbed `set_root`) isn't applied. Boost.Beast has no route registry (handlers compare `req.target()` by hand) and isn't extracted yet.
|
|
132
|
+
- **cpprestsdk listener routes**: only the path component of the listener's URL is extracted as a Route. Per-method handlers (`listener.support(methods::GET, ...)`) are not separately emitted — that would require tracking the listener's lifetime.
|
|
133
|
+
- **C++ shares vocabulary with C** (libcurl, OpenSSL, libsodium). Those patterns are duplicated here so a pure-C++ project without the C analyzer installed still gets full coverage. AttackMap's overlay deduplication handles double-firing.
|
|
134
|
+
- **Pure-template / header-only ORM** (sqlite_orm, sqlpp11): only basic detection via headers and `make_storage`; column-level extraction is out of scope.
|
|
135
|
+
|
|
136
|
+
## Native sinks
|
|
137
|
+
|
|
138
|
+
The analyzer emits function-local C/C++ weaknesses as `CodeWeakness` records (mlaify/AttackMap#189). Core turns them into findings, one per severity tier, with CWE/OWASP/ASVS ids.
|
|
139
|
+
|
|
140
|
+
| Kind (rule id) | Fires on | Not reported |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| `unbounded_copy` (CWE-120) | `gets`; `scanf`/`fscanf` `%s`/`%[` without a width; `strcpy`/`strcat`/`sprintf` `%s` whose source is traced to an input | a literal or untraced source; a source with an upper-bound check first (`strlen(s) < sizeof dst`, directly or through a length alias; `> 0` / `< 0` checks don't count); a sized destination (`malloc(strlen(s) + 1)`); `%.Ns`; a bounded read (`fgets`, `recv`, `%255s`) copied into an array at least as large |
|
|
143
|
+
| `format_string` (CWE-134) | a printf-family format (`printf`, `fprintf`, `sprintf`, `snprintf`, `syslog`, civetweb/mongoose `mg_printf`, `mg_http_reply`) that is not a constant | literals, `#define` and `static const` strings, literal ternaries, gettext `_()`, variadic and `va_list` wrappers forwarding their own `fmt`, untraced function results |
|
|
144
|
+
| `native_command_exec` (CWE-78) | `system`/`popen` with a non-constant command; `exec*` with an input-derived argument or a non-constant `sh -c` line | constant commands, `NULL`, an untraced `execv(path, args)` without a shell |
|
|
145
|
+
| `tainted_copy_length` (CWE-805) | `memcpy`/`memmove`/`strncpy`/`strncat` length traced to an input | lengths with an upper-bound check (`n > sizeof dst`, `ck_assert_int_lt(n, cap)`) or a clamp (`MIN`, `n > cap ? cap : n`, also inside the call) first, a destination allocated from the same length, a byte count returned by `recv`/`read` |
|
|
146
|
+
| `alloc_size_overflow` (CWE-680) | `malloc`/`realloc`/`alloca`/`new T[]` of a product with an input-derived factor | `calloc`, sums, untraced factors, a factor with an upper-bound check first or a `SIZE_MAX`/`__builtin_mul_overflow` guard |
|
|
147
|
+
|
|
148
|
+
**Sources**, traced per function through assignments, out-parameters and copy functions:
|
|
149
|
+
|
|
150
|
+
- **Request input:** parameters of a framework request type (bare names such as `Request`, `Rest::Request`, `request<...>`, `shared_ptr<Session>` count only in a file that uses that framework; `struct Request` never does) (cpp-httplib `Request`, Crow `crow::request`, Drogon `HttpRequestPtr`, Pistache `Rest::Request`, Boost.Beast `http::request<...>`, restbed `shared_ptr<Session>`/`shared_ptr<const Request>`); oat++ `ENDPOINT` `QUERY`/`PATH`/`HEADER`/`BODY_*` parameters; accessors such as `get_param_value` and `url_params` (other getters count only on a request-typed variable); and the C framework sources (civetweb, mongoose, libmicrohttpd).
|
|
151
|
+
- **Network input:** `recv`/`recvfrom`/`SSL_read`/`BIO_read`/`mbedtls_ssl_read`, and `read` on a socket-named descriptor.
|
|
152
|
+
- **Local input:** stdin (`fgets(..., stdin)`, `scanf`, `std::cin >>`, `std::getline(std::cin, ...)`), `argv`/`optarg` in a function that takes `argv`, `getenv`, and file reads.
|
|
153
|
+
|
|
154
|
+
Taint doesn't flow through calls to unknown functions (`gethostbyname(argv[1])`). A reassignment to a literal (`u = "default"`) clears it. A copy between two declared arrays where the destination is at least as large isn't reported.
|
|
155
|
+
|
|
156
|
+
**Severity and confidence:**
|
|
157
|
+
|
|
158
|
+
| Input traced to the sink | Severity / confidence |
|
|
159
|
+
|---|---|
|
|
160
|
+
| request or network | high / high |
|
|
161
|
+
| stdin, argv, env or file | medium / medium |
|
|
162
|
+
| none (only non-constant formats and commands are reported) | low / low |
|
|
163
|
+
|
|
164
|
+
Code under `examples/`, `demo/`, `samples/`, `contrib/` or `docs/` is capped at low. Test, fuzz and benchmark code (`test/`, `tests/`, `unittest/`, `fuzztest/`, `*_test.c`, ...) is skipped. `ATTACKMAP_INCLUDE_TESTS=1` scans it.
|
|
165
|
+
|
|
166
|
+
`native_sinks.py` is shared verbatim with attackmap-analyzer-c. Each file is analyzed by one of the two plugins (see `.h` ownership), so a weakness is never reported twice. It needs an `attackmap` core that exports `CodeWeakness` from `attackmap.sdk`. With an older core the analyzer still loads and emits no weaknesses.
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
attackmap_analyzer_cpp/__init__.py,sha256=lWdIq_sE3dcwrKHvJJxOtX3gaxQDYNZDfL_Ab8ubu3Q,61
|
|
2
|
+
attackmap_analyzer_cpp/analyzer.py,sha256=pcfQ4Xghp5_23ihbfgwRuMf7axmpkYH3WeyVm3wd1YU,28797
|
|
3
|
+
attackmap_analyzer_cpp/framework_routes.py,sha256=9OLYgrl4fX1eeSfOic1P3mgEWjWbgcfz9wTrc5vvfeM,11260
|
|
4
|
+
attackmap_analyzer_cpp/native_deps.py,sha256=EE-pcserTemXpfEnFoUa0OAYGV4EVtsWjwAXKr-iv-c,22933
|
|
5
|
+
attackmap_analyzer_cpp/native_sinks.py,sha256=LnbJL6sESAyD6zntYwhNUxtX9boIGzvriqxbnRvC5jo,72560
|
|
6
|
+
attackmap_analyzer_cpp-0.2.0.dist-info/licenses/LICENSE,sha256=vtPQVGUyxq359j0JmD3_eJaXyHmaHyjzaMOtaLwJc88,1097
|
|
7
|
+
attackmap_analyzer_cpp-0.2.0.dist-info/METADATA,sha256=IES0UlBNfeq0a2l0SoEt8-PIFlZn0CfNjoZ4WjR_Bro,15610
|
|
8
|
+
attackmap_analyzer_cpp-0.2.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
9
|
+
attackmap_analyzer_cpp-0.2.0.dist-info/entry_points.txt,sha256=Hov7DLdDs9qjDh1RjIXw4uveEu_GKhOERHSk2gTo0Wk,63
|
|
10
|
+
attackmap_analyzer_cpp-0.2.0.dist-info/top_level.txt,sha256=rIqk7py9tOCVX265ZVN-2mDCl7Y7Te2WcONxLm29ak0,23
|
|
11
|
+
attackmap_analyzer_cpp-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matthew Davis and AttackMap Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
attackmap_analyzer_cpp
|