├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── audit-scripts ├── README.md ├── aix-audit.sh ├── linux-audit.sh └── solaris-audit.sh ├── checks-database ├── aix.md ├── linux.md └── solaris.md ├── compare ├── README.md └── comparison.md ├── doc ├── AUTHORS ├── ChangeLog └── TODO └── unix-audit.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all project spaces, and it also applies when 49 | an individual is representing the project or its community in public spaces. 50 | Examples of representing a project or community include using an official 51 | project e-mail address, posting via an official social media account, or acting 52 | as an appointed representative at an online or offline event. Representation of 53 | a project may be further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [oss-conduct@cisco.com][conduct-email]. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | [conduct-email]: mailto:oss-conduct@cisco.com 69 | 70 | ## Attribution 71 | 72 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 73 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 74 | 75 | [homepage]: https://www.contributor-covenant.org 76 | 77 | For answers to common questions about this code of conduct, see 78 | https://www.contributor-covenant.org/faq 79 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | Thanks for your interest in contributing to `unix-audit`! Here are a few general guidelines on contributing and 4 | reporting bugs that we ask you to review. Following these guidelines helps to communicate that you respect the time of 5 | the contributors managing and developing this open source project. In return, they should reciprocate that respect in 6 | addressing your issue, assessing changes, and helping you finalize your pull requests. In that spirit of mutual respect, 7 | we endeavor to review incoming issues and pull requests within 10 days, and will close any lingering issues or pull 8 | requests after 60 days of inactivity. 9 | 10 | Please note that all of your interactions in the project are subject to our [Code of Conduct](/CODE_OF_CONDUCT.md). This 11 | includes creation of issues or pull requests, commenting on issues or pull requests, and extends to all interactions in 12 | any real-time space e.g., Slack, Discord, etc. 13 | 14 | ## Reporting Issues 15 | 16 | Before reporting a new issue, please ensure that the issue was not already reported or fixed by searching through our 17 | [issues list](https://github.com/CiscoCXSecurity/unix-audit/issues). 18 | 19 | When creating a new issue, please be sure to include a **title and clear description**, as much relevant information as 20 | possible, and, if possible, a test case. 21 | 22 | **If you discover a security bug, please do not report it through GitHub. Instead, please see security procedures in 23 | [SECURITY.md](/SECURITY.md).** 24 | 25 | ## Sending Pull Requests 26 | 27 | Before sending a new pull request, take a look at existing pull requests and issues to see if the proposed change or fix 28 | has been discussed in the past, or if the change was already implemented but not yet released. 29 | 30 | We expect new pull requests to include tests for any affected behavior, and, as we follow semantic versioning, we may 31 | reserve breaking changes until the next major version release. 32 | 33 | ## Other Ways to Contribute 34 | 35 | We welcome anyone that wants to contribute to `unix-audit` to triage and reply to open issues to help troubleshoot 36 | and fix existing bugs. Here is what you can do: 37 | 38 | - Help ensure that existing issues follows the recommendations from the _[Reporting Issues](#reporting-issues)_ section, 39 | providing feedback to the issue's author on what might be missing. 40 | - Review existing pull requests, and testing patches against real existing applications that use `unix-audit`. 41 | - Write a test, or add a missing test case to an existing test. 42 | 43 | Thanks again for your interest on contributing to `unix-audit`! 44 | 45 | :heart: 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2020, Tim Brown 2 | Copyright Ciso Systems, Inc. and its affiliates 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Cisco International Ltd nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL CISCO INTERNATIONAL LTD BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unix-audit 2 | Framework for generating audit commands for Unix security audits. 3 | 4 | unix-audit allows you to maintain a list of commands in markdown (.md) format, then generate audit scripts from those markdown pages. You can [view the markdown database files here](checks-database/). Feel free to maintain your own database of checks or to contribute back to this public repository (also see [contributing](CONTRIBUTING.md)). 5 | 6 | You can optionally tag your commands (or whole sections of commands) to enable generation of scripts that contain only a subset of your checks database. This can be useful if you need to perform different types of audit (e.g. you might have a normal security audit, a bug-hunting audit, a privilege escalation check, checks for detective controls, checks for exposed secrets, commands that help you collect data for graphing, a quick audit, a slow audit, audits that generate extra files, audits that don't generate extra files, etc.) 7 | 8 | The markdown database format allows the use of comments - in fact only code blocks and titles are used during script generation, everything else is ignored. This can help to document your commands for users. 9 | 10 | The markdown format (parsed or unparsed) can also make it easier to identify gaps in your scripts - e.g. maybe your Solaris audits don't include commands for all the checks performed on Linux. Gaps can be more difficult to find if you only maintain source code. 11 | 12 | # Quick Start 13 | unix-audit can generate shell scripts containing the commands you want to run on the target system: 14 | ``` 15 | python3 unix-audit.py generate ./checks-database/ linux all > audit-scripts/linux-audit.sh 16 | python3 unix-audit.py generate ./checks-database/ solaris all > audit-scripts/solaris-audit.sh 17 | python3 unix-audit.py generate ./checks-database/ aix all > audit-scripts/aix-audit.sh 18 | python3 unix-audit.py generate ./checks-database/ linux exploit-mitigation,software-installed > audit-scripts/smaller-audit.sh 19 | ``` 20 | You can get a list of supported platforms and available tags by specifying using "list" mode: 21 | ``` 22 | $ python3 unix-audit.py list ./checks-database/ 23 | ... 24 | Available platforms: aix, linux, solaris 25 | Available tags: network-stack-tuning, logging, privilege-escalation, file-permissions, exploit-mitigation, authentication, resource-limits, access-control, common-services, networking, cryptography, environment, software-installed, informational, important-file-locations 26 | ``` 27 | Upload the script to the target system (e.g. scp or copy-paste), run it and collect the output, e.g. 28 | ``` 29 | # sh audit.sh > audit-output.sh 30 | ``` 31 | Then copy the output file back to your own systems for analysis. 32 | 33 | The public version of unix-audit doesn't analyze data, it just collects it. We hope to add a feature for analyzing collected data too in future. 34 | 35 | # Usage 36 | ``` 37 | Usage: unix-audit.py mode args 38 | 39 | Modes: 40 | python3 unix-audit.py list 41 | python3 unix-audit.py generate 42 | python3 unix-audit.py compare 43 | 44 | List mode - lists the platforms and tags available for other modes. Examples: 45 | 46 | python3 unix-audit.py list ./checks-database/ 47 | 48 | Generate mode - used to generate an audit script from md files. Examples: 49 | 50 | python3 unix-audit.py generate ./checks-database/ linux all > audit-scripts/linux-audit.sh 51 | python3 unix-audit.py generate ./checks-database/ aix all > audit-scripts/aix-audit.sh 52 | python3 unix-audit.py generate ./checks-database/ solaris all > audit-scripts/solaris-audit.sh 53 | 54 | Compare mode - find differences in commands for 2 or more platforms. Examples: 55 | 56 | python unix-audit.py compare ./checks-database/ all all > compare/comparison.md 57 | python3 unix-audit.py compare ./checks-database/ linux,solaris > linux-solaris-compare.md 58 | python3 unix-audit.py compare ./checks-database/ all authentication,logging > linux-solaris-compare.md 59 | ``` 60 | List mode: 61 | ``` 62 | $ python3 unix-audit.py list ./checks-database/ 63 | Available platforms: solaris, aix, linux 64 | Available tags: important-file-locations, informational, authentication, software-installed, logging, resource-limits, networking, exploit-mitigation, cryptography, network-stack-tuning, file-permissions, environment, access-control, privilege-escalation, common-services 65 | ``` 66 | # What is unix-audit used for? 67 | 68 | unix-audit is mostly used by Cisco's offensive security testing teams (penetration testers and red teamers) to collect information from systems they are asked to audit. The collected data is parsed and analysed offline and ultimately used to generate details of security weakenesses and corresponding recommendations for customers. The depth of such audits can be fairly extensive for Build Review type activities. Conversely, it can be fairly light for ad-hoc checks for compromised systems during penetration tests. 69 | 70 | Analysis tools for parsing have not been released publicly at the time of writing (although you can check out [sudo-parser](https://github.com/CiscoCXSecurity/sudo-parser) if that's of interest). 71 | 72 | There are lots of other use-cases and potential use-cases too, e.g. 73 | * Supporting password strength audits (collecting shadow files or similar) 74 | * Supporting the graphing of SSH trust relationships 75 | * Bug hunting for a particular class of security vulnerability (we like finding [RPATH vulnerabilities](https://github.com/CiscoCXSecurity/presentations/blob/master/BTLCC.pdf)) 76 | * Searching for exposed secrets in home directories 77 | 78 | If you have commands that your team needs to run on customer systems, it should be easy to adapt for your use-case too. 79 | 80 | Also check out [unix_collector](https://github.com/CiscoCXSecurity/unix_collector) which is maintained by Cisco's teams that focus on detection and response. 81 | 82 | # How to update commands / scripts 83 | 84 | To update the [checks-database](checks-database/), just go ahead and edit the markdown files - using the github editor or your preferred markdown editor. 85 | 86 | After updating the checks database, any existing scripts will be out of date and you'll need to regenerate them. 87 | 88 | To "compile", use the unix-audit.py in "generate" mode as directed above. 89 | 90 | # Tips on running audit scripts 91 | 92 | Remember the following when running audit scripts: 93 | * Collect the output from your script by redirecting output, using "script", "tee" or somethign similar. 94 | * Commands in the checks database generally don't create files, but some do. So run in a clean directory so you can easily identify any other created files that you may want to retrieve at the end of the audit. 95 | * Don't fill up the disk partition. Your script might run for a long time and generate a lot of output. Check there's plenty of disk space before you start. 96 | * Be considerate about degrading system performance. Some commands can use a lot of CPU or disk I/O. In practice we haven't noticed problems. But if you were to audit 100 systems simultaneously and they all shared a resource (e.g. hypervisor/SAN), you might run into problems. 97 | * Tidy up after yourself and avoid leaving sensitive data lying around. 98 | 99 | # How to check for gaps in your scripts 100 | 101 | If one of the platforms you audit (e.g. AIX) had less checks than another platform (e.g. Linux), how would you know? unix-audit seeks to address this in two ways: 102 | * Encourage the writing of markdown files in a common format (and each team can choose a format that works for them). This supports manual side-by-side comparison of docs for two different platforms. 103 | * Using a markdown parser to compare checks for two different platforms. 104 | 105 | Use unix-audit in compare mode to identify checks (markdown titles) that exist for one platform but not another: 106 | ``` 107 | unix-audit.py compare ./checks-database/ linux solaris 108 | ``` 109 | See [comparison.md](compare/comparison.md) for example output. 110 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policies and Procedures 2 | 3 | This document outlines security procedures and general policies for the 4 | `unix-audit` project. 5 | 6 | - [Reporting a Bug](#reporting-a-bug) 7 | - [Disclosure Policy](#disclosure-policy) 8 | - [Comments on this Policy](#comments-on-this-policy) 9 | 10 | ## Reporting a Bug 11 | 12 | The `unix-audit` team and community take all security bugs in 13 | `unix-audit` seriously. Thank you for improving the security of 14 | `unix-audit`. We appreciate your efforts and responsible disclosure and 15 | will make every effort to acknowledge your contributions. 16 | 17 | Report security bugs by emailing `oss-security@cisco.com`. 18 | 19 | The lead maintainer will acknowledge your email within 48 hours, and will send a 20 | more detailed response within 48 hours indicating the next steps in handling 21 | your report. After the initial reply to your report, the security team will 22 | endeavor to keep you informed of the progress towards a fix and full 23 | announcement, and may ask for additional information or guidance. 24 | 25 | ## Disclosure Policy 26 | 27 | When the security team receives a security bug report, they will assign it to a 28 | primary handler. This person will coordinate the fix and release process, 29 | involving the following steps: 30 | 31 | - Confirm the problem and determine the affected versions. 32 | - Audit code to find any potential similar problems. 33 | - Prepare fixes for all releases still under maintenance. These fixes will be 34 | released as quickly as possible. 35 | 36 | ## Comments on this Policy 37 | 38 | If you have suggestions on how this process could be improved please submit a 39 | pull request. 40 | -------------------------------------------------------------------------------- /audit-scripts/README.md: -------------------------------------------------------------------------------- 1 | # Generate Mode 2 | 3 | This directory contains example files for the "generate" mode of unix-audit. 4 | 5 | The purpose of "generate" mode is to create an audit scripts using a subset of the checks database. 6 | 7 | Example command lines to generate audit scripts: 8 | 9 | ``` 10 | python3 unix-audit.py generate ./checks-database/ aix all > audit-scripts/aix-audit.sh 11 | python3 unix-audit.py generate ./checks-database/ linux all > audit-scripts/linux-audit.sh 12 | python3 unix-audit.py generate ./checks-database/ solaris all > audit-scripts/solaris-audit.sh 13 | ``` 14 | 15 | Consider scripts in this directory to be samples only. They are not guaranteed to reflect the latest checks database. 16 | -------------------------------------------------------------------------------- /audit-scripts/aix-audit.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2020, Tim Brown 2 | # Copyright Ciso Systems, Inc. and its affiliates 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the Cisco International Ltd nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CISCO INTERNATIONAL LTD BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | echo "=== AIX > Informational > Hostname"=== 27 | hostname 28 | 29 | echo "=== AIX > Informational > Kernel version"=== 30 | uname -a 31 | 32 | echo "=== AIX > Informational > Network interfaces"=== 33 | ifconfig -a 34 | 35 | echo "=== AIX > Environment > PCI cards accessible"=== 36 | lsdev -C 37 | 38 | echo "=== AIX > Environment > USB peripherals accessible"=== 39 | lsdev -C 40 | 41 | echo "=== AIX > Networking > ARP"=== 42 | arp -an 43 | 44 | echo "=== AIX > Networking > Routing"=== 45 | netstat -rn 46 | 47 | echo "=== AIX > Networking > Name services"=== 48 | cat /etc/netsvc.conf 49 | 50 | echo "=== AIX > Networking > Hosts"=== 51 | cat /etc/hosts 52 | 53 | echo "=== AIX > Networking > DNS"=== 54 | cat /etc/resolv.conf 55 | 56 | echo "=== AIX > Networking > Internet"=== 57 | ping -c 5 www.google.co.uk 58 | ping -c 5 8.8.8.8 59 | 60 | echo "=== AIX > Networking > Listening services"=== 61 | netstat -an | grep -v "unix" | grep "LISTEN" 62 | 63 | echo "=== AIX > Networking > IPv6"=== 64 | ifconfig lo0 | grep "::1" 65 | 66 | echo "=== AIX > Network stack tuning > IP forwarding"=== 67 | /usr/sbin/no -a | grep "ipforwarding" 68 | 69 | echo "=== AIX > Access control > Firewall configured"=== 70 | lsfilt 71 | 72 | echo "=== AIX > Access control > TCP wrappers used"=== 73 | cat /etc/hosts.allow 74 | cat /etc/hosts.deny 75 | 76 | echo "=== AIX > Access control > .rhosts used"=== 77 | find / -name .rhosts -ls 78 | 79 | echo "=== AIX > Access control > hosts.equiv used"=== 80 | cat /etc/hosts.equiv 81 | 82 | echo "=== AIX > Access control > .netrc used"=== 83 | find / -name .netrc -ls 84 | 85 | echo "=== AIX > Access control > Remote X"=== 86 | netstat -an | grep "LISTEN" | egrep "6000|177" 87 | 88 | echo "=== AIX > Access control > Accounts with non-standard shells"=== 89 | grep -v "/sh$" /etc/passwd 90 | 91 | echo "=== AIX > Access control > Valid shells"=== 92 | cat /etc/shells 93 | 94 | echo "=== AIX > Access control > SSH ACLs configured"=== 95 | grep "Match" /etc/ssh/sshd_config 96 | 97 | echo "=== AIX > Access control > SSH user logins"=== 98 | egrep "AllowUsers|DenyUsers|AllowGroups|DenyGroups" /etc/ssh/sshd_config 99 | 100 | echo "=== AIX > Access control > SSH root logins"=== 101 | grep "PermitRootLogin" /etc/ssh/sshd_config 102 | 103 | echo "=== AIX > Access control > SSH TCP forwarding"=== 104 | grep "AllowTCPForwarding" /etc/ssh/sshd_config 105 | 106 | echo "=== AIX > Access control > SSH gateway ports"=== 107 | grep "GatewayPorts" /etc/ssh/sshd_config 108 | 109 | echo "=== AIX > Access control > SSH VPN"=== 110 | grep "PermitTunnel" /etc/ssh/sshd_config 111 | 112 | echo "=== AIX > Access control > SSH agent forwarding"=== 113 | grep "AllowAgentForwarding" /etc/ssh/sshd_config 114 | 115 | echo "=== AIX > Access control > SSH X11 forwarding"=== 116 | grep "X11Forwarding" /etc/ssh/sshd_config 117 | 118 | echo "=== AIX > Access control > SSH binds X11 to localhost"=== 119 | grep "X11UseLocalhost" /etc/ssh/sshd_config 120 | 121 | echo "=== AIX > Access control > SSH reads environment from user file"=== 122 | grep "PermitUserEnvironment" /etc/ssh/sshd_config 123 | 124 | echo "=== AIX > Access control > SSH accepts environment variables"=== 125 | grep "AcceptEnv" /etc/ssh/sshd_config 126 | 127 | echo "=== AIX > Access control > SSH looks up connections in DNS"=== 128 | grep "UseDNS" /etc/ssh/sshd_config 129 | 130 | echo "=== AIX > Access control > SSH uses privilege separation"=== 131 | grep "UsePrivilegeSeparation" /etc/ssh/sshd_config 132 | 133 | echo "=== AIX > Access control > .shosts used"=== 134 | find / -name .shosts -ls 135 | 136 | echo "=== AIX > Access control > shosts.equiv used"=== 137 | cat /etc/shosts.equiv 138 | 139 | echo "=== AIX > Access control > SSH allows .rhosts"=== 140 | grep "IgnoreRhosts" /etc/ssh/sshd_config 141 | 142 | echo "=== AIX > Access control > SSH public/private keys used"=== 143 | find / -name id_dsa -o -name id_dsa.pub -o -name id_rsa -o -name id_rsa.pub -o -name authorized_keys -ls 144 | 145 | echo "=== AIX > Access control > SSH sessions are throttled"=== 146 | egrep "MaxAuthTries|MaxSessions|MaxStartups" /etc/ssh/sshd_config 147 | 148 | echo "=== AIX > Access control > FTP users disallowed"=== 149 | cat /etc/ftpusers 150 | 151 | echo "=== AIX > Access control > NFS shares"=== 152 | cat /etc/exports 153 | 154 | echo "=== AIX > Access control > Secure consoles"=== 155 | cat /etc/security/user 156 | 157 | echo "=== AIX > Authentication > Banner"=== 158 | cat /etc/issue 159 | 160 | echo "=== AIX > Authentication > MOTD"=== 161 | cat /etc/motd 162 | 163 | echo "=== AIX > Authentication > Passwords"=== 164 | cat /etc/passwd 165 | cat /etc/security/passwd 166 | 167 | echo "=== AIX > Authentication > SNMP community strings"=== 168 | grep "community" /etc/snmpd.conf 169 | 170 | echo "=== AIX > Authentication > Login policy"=== 171 | cat /etc/security/login.cfg 172 | 173 | echo "=== AIX > Authentication > Password aging"=== 174 | cat /etc/security/users 175 | 176 | echo "=== AIX > Authentication > Password minimum strength"=== 177 | cat /etc/security/users 178 | 179 | echo "=== AIX > Authentication > Unlocked accounts"=== 180 | cat /etc/security/passwd 181 | 182 | echo "=== AIX > Authentication > Session timeout"=== 183 | echo $TMOUT 184 | 185 | echo "=== AIX > Authentication > SSH shows banner"=== 186 | grep "Banner" /etc/ssh/sshd_config 187 | 188 | echo "=== AIX > Authentication > SSH shows MOTD"=== 189 | grep "PrintMotd" /etc/ssh/sshd_config 190 | 191 | echo "=== AIX > Authentication > SSH allows empty passwords"=== 192 | grep "PermitEmptyPasswords" /etc/ssh/sshd_config 193 | 194 | echo "=== AIX > Cryptography > known_hosts encrypted"=== 195 | cat /.ssh/known_hosts 196 | 197 | echo "=== AIX > Cryptography > SSH protocol"=== 198 | grep "Protocol" /etc/ssh/sshd_config 199 | 200 | echo "=== AIX > Cryptography > SSH protocol 1 key regeneration"=== 201 | grep "KeyRegenerationInterval" /etc/ssh/sshd_config 202 | 203 | echo "=== AIX > Cryptography > SSH protocol 1 key size"=== 204 | grep "ServerKeyBits" /etc/ssh/sshd_config 205 | 206 | echo "=== AIX > Cryptography > SSH protocol 2 public key authentication"=== 207 | grep "PubkeyAuthentication" /etc/ssh/sshd_config 208 | 209 | echo "=== AIX > Cryptography > SSH allows .rhosts with protocol 1 RSA"=== 210 | grep "RhostsRSAAuthentication" /etc/ssh/sshd_config 211 | 212 | echo "=== AIX > Cryptography > SSH allows protocol 1 RSA"=== 213 | grep "RSAAuthentication" /etc/ssh/sshd_config 214 | 215 | echo "=== AIX > Cryptography > SSH password based authentication"=== 216 | grep "PasswordAuthentication" /etc/ssh/sshd_config 217 | 218 | echo "=== AIX > Cryptography > SSH ciphers"=== 219 | grep "Ciphers" /etc/ssh/sshd_config 220 | 221 | echo "=== AIX > Cryptography > SSH MACs"=== 222 | grep "MACs" /etc/ssh/sshd_config 223 | 224 | echo "=== AIX > Cryptography > Blacklisted keys"=== 225 | grep "PermitBlacklistedKeys" /etc/ssh/sshd_config 226 | 227 | echo "=== AIX > Cryptography > Crypto used for shadow"=== 228 | grep "pwd_algorithm" /etc/security/login.cfg 229 | 230 | echo "=== AIX > Software installed > OS release"=== 231 | oslevel -sq 232 | oslevel -rq 233 | 234 | echo "=== AIX > Software installed > Packages installed"=== 235 | lslpp -Lc 236 | rpm -q -a 237 | 238 | echo "=== AIX > Software installed > Processes"=== 239 | ps -aef 240 | 241 | echo "=== AIX > Software installed > Services"=== 242 | lssrc -a 243 | lssrc -a | grep -v "Sub" | while read subsystem _ 244 | do 245 | echo "Subsystem: $subsystem" 246 | lssrc -ls $subsystem 247 | done 248 | 249 | echo "=== AIX > Software installed > Development tools"=== 250 | find / -type f \( -name perl -o -name gcc -o -name javac -o -name python -o -name ruby -o -name gdb \) 251 | 252 | echo "=== AIX > Software installed > 3rd party software"=== 253 | find /usr/local -ls 254 | find /opt -ls 255 | 256 | echo "=== AIX > Logging > Time synchronisation"=== 257 | ps -aef | grep "ntp" 258 | 259 | echo "=== AIX > Logging > Remote logging"=== 260 | grep "@" /etc/syslog.conf 261 | 262 | echo "=== AIX > Logging > Cron logging"=== 263 | grep "cron" /etc/syslog.conf 264 | 265 | echo "=== AIX > Resource limits > Configured limits"=== 266 | cat /etc/security/limits 267 | 268 | echo "=== AIX > Resource limits > Running limits"=== 269 | ulimit -a 270 | 271 | echo "=== AIX > Resource limits > Disk quotas"=== 272 | lsfs | grep "Quota" 273 | 274 | echo "=== AIX > File permissions > Init umask"=== 275 | grep "umask" /etc/rc.* 276 | 277 | echo "=== AIX > File permissions > FTP umask"=== 278 | grep "ftpd" /etc/inetd.conf 279 | 280 | echo "=== AIX > File permissions > Root umask"=== 281 | umask 282 | 283 | echo "=== AIX > File permissions > User umask"=== 284 | grep "umask" /home/*/.[a-z]* 285 | grep "umask" /etc/security/.profile 286 | grep "umask" /etc/profile 287 | cat /etc/security/user 288 | 289 | echo "=== AIX > File permissions > Service umasks"=== 290 | grep "umask" /etc/rc*.d/* 291 | 292 | echo "=== AIX > File permissions > World readable files / directories"=== 293 | find / -perm -o+r -ls 294 | 295 | echo "=== AIX > File permissions > World writable files / directories"=== 296 | find / -perm -o+w -ls 297 | 298 | echo "=== AIX > File permissions > Group writable files / directories"=== 299 | find / -perm -o+w -ls 300 | 301 | echo "=== AIX > File permissions > Unowned files / directories"=== 302 | find / -nouser -ls 303 | 304 | echo "=== AIX > File permissions > Ungrouped files / directories"=== 305 | find / -nogroup -ls 306 | 307 | echo "=== AIX > File permissions > Log files"=== 308 | find /var/log /var/adm -ls 309 | 310 | echo "=== AIX > File permissions > SSH strict mode"=== 311 | grep "StrictModes" /etc/ssh/sshd_config 312 | 313 | echo "=== AIX > File permissions > Root home"=== 314 | find /root -ls 315 | 316 | echo "=== AIX > Exploit mitigation > Active mounts secure"=== 317 | mount | grep -v "nosetuid" 318 | mount | grep -v "noexec" 319 | lsfs 320 | 321 | echo "=== AIX > Exploit mitigation > Configured mounts secure"=== 322 | cat /etc/filesystems 323 | 324 | echo "=== AIX > Exploit mitigation > Separate partitions"=== 325 | mount | grep "/var" 326 | mount | grep "/var/log" 327 | mount | grep "/home" 328 | 329 | echo "=== AIX > Exploit mitigation > Cron users"=== 330 | cat /var/adm/cron/cron.allow /var/adm/cron/cron.deny 331 | 332 | echo "=== AIX > Exploit mitigation > At users"=== 333 | cat /var/adm/cron/at.allow /var/adm/cron/at.deny 334 | 335 | echo "=== AIX > Exploit mitigation > Non executable stack"=== 336 | sedmgr 337 | 338 | echo "=== AIX > Privilege escalation > Init scripts run"=== 339 | cat /etc/inittab 340 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 341 | do 342 | echo "File: $file" 343 | ls -la $file 344 | done 345 | ls -la /etc/rc.* 346 | 347 | echo "=== AIX > Privilege escalation > At scripts run"=== 348 | for file in /var/spool/atjobs/* 349 | do 350 | echo "File: $file" 351 | ls -l $file 352 | cat $file 353 | done 354 | 355 | echo "=== AIX > Privilege escalation > Cron scripts run"=== 356 | for file in /var/spool/cron/* 357 | do 358 | echo "File: $file" 359 | ls -l $file 360 | cat $file 361 | done 362 | 363 | echo "=== AIX > Privilege escalation > Default path"=== 364 | echo $PATH 365 | 366 | echo "=== AIX > Privilege escalation > User paths"=== 367 | grep "PATH" /home/*/.[a-z]* 368 | 369 | echo "=== AIX > Privilege escalation > Init paths"=== 370 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 371 | do 372 | echo "File: $file" 373 | grep "PATH" $file 374 | done 375 | grep "PATH" /etc/rc.* 376 | 377 | echo "=== AIX > Privilege escalation > Default linker path"=== 378 | grep "LD_LIBRARY_PATH" /etc/profile 379 | echo $LD_LIBRARY_PATH 380 | 381 | echo "=== AIX > Privilege escalation > User linker paths"=== 382 | egrep "LIBPATH|LD_LIBRARY_PATH" /home/*/.[a-z]* 383 | 384 | echo "=== AIX > Privilege escalation > Init linker paths"=== 385 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 386 | do 387 | echo "File: $file" 388 | egrep "LIBPATH|LD_LIBRARY_PATH" $file 389 | done 390 | egrep "LIBPATH|LD_LIBRARY_PATH" /etc/rc.* 391 | 392 | echo "=== AIX > Privilege escalation > SetUID files"=== 393 | find / -perm -u+s -type f -ls 394 | 395 | echo "=== AIX > Privilege escalation > SetGID files"=== 396 | find / -perm -g+s -type f -ls 397 | 398 | echo "=== AIX > Privilege escalation > Sudo configuration"=== 399 | cat /etc/sudoers 400 | 401 | echo "=== AIX > Common services > SSH running config"=== 402 | sshd -T 403 | 404 | echo "=== AIX > Common services > Web server config"=== 405 | find / -name httpd.conf | while read file 406 | do 407 | echo "File: $file" 408 | ls -l $file 409 | cat $file 410 | done 411 | 412 | echo "=== AIX > Common services > Web server cgi-bin"=== 413 | find /usr/lib -name cgi-bin | while read file 414 | do 415 | echo "File: $file" 416 | ls -l $file 417 | done 418 | 419 | 420 | -------------------------------------------------------------------------------- /audit-scripts/linux-audit.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2020, Tim Brown 2 | # Copyright Ciso Systems, Inc. and its affiliates 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the Cisco International Ltd nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CISCO INTERNATIONAL LTD BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | echo "=== Linux > Informational > Date"=== 27 | date 28 | 29 | echo "=== Linux > Informational > Hostname"=== 30 | hostname 31 | 32 | echo "=== Linux > Informational > Kernel version"=== 33 | uname -a 34 | 35 | echo "=== Linux > Informational > Network interfaces (ifconfig)"=== 36 | ifconfig -a 37 | 38 | echo "=== Linux > Informational > Network interfaces (ip)"=== 39 | ip -a 40 | 41 | echo "=== Linux > Informational > Running as"=== 42 | id 43 | 44 | echo "=== Linux > Environment > PCI cards accessible"=== 45 | lspci 46 | 47 | echo "=== Linux > Environment > USB peripherals accessible"=== 48 | lsusb 49 | 50 | echo "=== Linux > Environment > Boot flags"=== 51 | cat /proc/cmdline 52 | 53 | echo "=== Linux > Environment > Kernel logs"=== 54 | dmesg 55 | 56 | echo "=== Linux > Environment > Kernel config"=== 57 | cat /boot/config-`uname -r` 58 | 59 | echo "=== Linux > Environment > Loaded kernel modules"=== 60 | lsmod 61 | 62 | echo "=== Linux > Environment > Kernel modules supported"=== 63 | grep "CONFIG_MODULES" /boot/config-`uname -r` 64 | 65 | echo "=== Linux > Environment > Kernel modules"=== 66 | sysctl kernel.modules_disabled 67 | 68 | echo "=== Linux > Environment > Grub password set"=== 69 | grep "password" /boot/grub/menu.lst 70 | 71 | echo "=== Linux > Environment > Ctrl-alt-delete"=== 72 | grep "ctrlaltdel" /etc/inittab 73 | 74 | echo "=== Linux > Environment > Kernel debugging"=== 75 | grep "sysrq" /etc/sysctl.conf 76 | 77 | echo "=== Linux > Environment > Kernel hardening"=== 78 | cat /etc/sysctl.conf 79 | 80 | echo "=== Linux > Environment > Active kernel hardening"=== 81 | sysctl -a 82 | 83 | echo "=== Linux > Environment > Host is KVM"=== 84 | cat /proc/cpuinfo | grep -i "qemu" 85 | 86 | echo "=== Linux > Environment > Host is VMware"=== 87 | dmidecode | grep -i "vmware" 88 | 89 | echo "=== Linux > Environment > Host is VirtualBox"=== 90 | dmidecode | grep -i "virtualbox" 91 | 92 | echo "=== Linux > Environment > Host is Xen"=== 93 | dmidecode | grep -i "xen" 94 | 95 | echo "=== Linux > Environment > Host is container"=== 96 | cat /proc/1/cgroup 97 | 98 | echo "=== Linux > Environment > Containers"=== 99 | docker ps -a 100 | 101 | echo "=== Linux > Environment > K8s cluster"=== 102 | kubectl config view 103 | 104 | echo "=== Linux > Environment > Environment variables set"=== 105 | env 106 | 107 | echo "=== Linux > Environment > Currently logged in"=== 108 | who 109 | 110 | echo "=== Linux > Environment > Logins"=== 111 | last 112 | 113 | echo "=== Linux > Networking > ARP"=== 114 | arp -an 115 | 116 | echo "=== Linux > Networking > ARP (using ip)"=== 117 | ip -4 neigh show 118 | 119 | echo "=== Linux > Networking > IPv6 neighbor table"=== 120 | ip -6 neigh show 121 | 122 | echo "=== Linux > Networking > Routing (netstat)"=== 123 | netstat -rn 124 | 125 | echo "=== Linux > Networking > Routing (ip)"=== 126 | ip route show 127 | 128 | echo "=== Linux > Networking > Name services"=== 129 | cat /etc/nsswitch.conf 130 | 131 | echo "=== Linux > Networking > Hosts"=== 132 | cat /etc/hosts 133 | 134 | echo "=== Linux > Networking > DNS"=== 135 | cat /etc/resolv.conf 136 | 137 | echo "=== Linux > Networking > Internet (IPv4)"=== 138 | ping -4 -c 5 www.google.co.uk 139 | ping -c 5 8.8.8.8 140 | 141 | echo "=== Linux > Networking > Internet (IPv6)"=== 142 | ping -6 -c 5 www.google.co.uk 143 | ping -c 5 2001:4860:4860::8888 144 | 145 | echo "=== Linux > Networking > Web accessible (IPv4)"=== 146 | wget -O - https://216.58.213.164 147 | wget -O -4 - https://www.google.com 148 | curl https://216.58.213.164 149 | curl -4 https://www.google.com 150 | 151 | echo "=== Linux > Networking > Web accessible (IPv6)"=== 152 | wget -O - https://[2600::] 153 | wget -6 -O - https://www.google.com 154 | curl https://[2600::] 155 | curl -6 https://www.google.com 156 | 157 | echo "=== Linux > Networking > Internet by proxy"=== 158 | echo $http_proxy 159 | echo $https_proxy 160 | echo $ftp_proxy 161 | 162 | echo "=== Linux > Networking > Listening services (netstat)"=== 163 | netstat -anp | grep -v "unix" | grep "LISTEN" 164 | 165 | echo "=== Linux > Networking > Listening services (socket stat)"=== 166 | ss -tulpan | grep LISTEN 167 | 168 | echo "=== Linux > Networking > RPC services"=== 169 | rpcinfo -p 170 | 171 | echo "=== Linux > Networking > IPv6 (ifconfig)"=== 172 | ifconfig lo | grep "::1" 173 | 174 | echo "=== Linux > Networking > IPv6 (ip)"=== 175 | ip addr show dev lo | grep ::1 176 | 177 | echo "=== Linux > Networking > Network traffic"=== 178 | # Possible alternative to which for non Linux systems: 179 | # if ! [ -x "$(command -v tcpdump)" ]; then 180 | if ! [ "$(which tcpdump)" ]; then 181 | echo 'Error: tcpdump is not installed.' >&2 182 | else 183 | # Capture traffic on all interfaces, for 60 seconds: 184 | # -G 60 (rotate dump files every x seconds) 185 | # -W 1 (limit number of dump files) 186 | # Filter out traffic on port 22 to avoid feedback loop: 187 | # port not 22 188 | tcpdump -G 60 -W 1 -i any -s 65535 port not 22 -w packet_capture-`hostname`.pcap 189 | fi 190 | tar cvf packet_capture-`hostname`.tar packet_capture-`hostname`.pcap 191 | gzip packet_capture-`hostname`.tar 192 | rm packet_capture-`hostname`.pcap 193 | 194 | echo "=== Linux > Network stack tuning > Syncookies"=== 195 | cat /proc/sys/net/ipv4/tcp_syncookies 196 | grep "syncookies" /etc/sysctl.conf 197 | 198 | echo "=== Linux > Network stack tuning > IP forwarding"=== 199 | cat /proc/sys/net/ipv4/ip_forward 200 | grep "ip_forward" /etc/sysctl.conf 201 | 202 | echo "=== Linux > Network stack tuning > Network shares mounted"=== 203 | mount | grep "cifs" 204 | mount | grep "nfs" 205 | 206 | echo "=== Linux > Access control > Firewall configured"=== 207 | iptables -L 208 | ip6tables -L 209 | 210 | echo "=== Linux > Access control > TCP wrappers used"=== 211 | cat /etc/hosts.allow 212 | cat /etc/hosts.deny 213 | 214 | echo "=== Linux > Access control > .rhosts used"=== 215 | find / -name .rhosts -ls 216 | 217 | echo "=== Linux > Access control > hosts.equiv used"=== 218 | cat /etc/hosts.equiv 219 | 220 | echo "=== Linux > Access control > .netrc used"=== 221 | find / -name .netrc -ls 222 | 223 | echo "=== Linux > Access control > Remote X"=== 224 | grep "nolistentcp" /etc/X11/xdm/Xservers /etc/kde/kdm/Xservers /etc/X11/gdm/gdm.conf /etc/X11/xinit/xserverrc 225 | 226 | echo "=== Linux > Access control > X root logins"=== 227 | grep "AllowRootLogin" /etc/X11/xdm/kdmrc 228 | 229 | echo "=== Linux > Access control > Account statuses"=== 230 | passwd -S -a 231 | 232 | echo "=== Linux > Access control > Accounts with non-standard shells"=== 233 | grep -v "/bash$" /etc/passwd 234 | 235 | echo "=== Linux > Access control > Valid shells"=== 236 | cat /etc/shells 237 | 238 | echo "=== Linux > Access control > SSH ACLs configured"=== 239 | grep "Match" /etc/ssh/sshd_config 240 | 241 | echo "=== Linux > Access control > SSH user logins"=== 242 | egrep "AllowUsers|DenyUsers|AllowGroups|DenyGroups" /etc/ssh/sshd_config 243 | 244 | echo "=== Linux > Access control > SSH root logins"=== 245 | grep "PermitRootLogin" /etc/ssh/sshd_config 246 | 247 | echo "=== Linux > Access control > SSH TCP forwarding"=== 248 | grep "AllowTCPForwarding" /etc/ssh/sshd_config 249 | 250 | echo "=== Linux > Access control > SSH gateway ports"=== 251 | grep "GatewayPorts" /etc/ssh/sshd_config 252 | 253 | echo "=== Linux > Access control > SSH VPN"=== 254 | grep "PermitTunnel" /etc/ssh/sshd_config 255 | 256 | echo "=== Linux > Access control > SSH agent forwarding"=== 257 | grep "AllowAgentForwarding" /etc/ssh/sshd_config 258 | 259 | echo "=== Linux > Access control > SSH X11 forwarding"=== 260 | grep "X11Forwarding" /etc/ssh/sshd_config 261 | 262 | echo "=== Linux > Access control > SSH binds X11 to localhost"=== 263 | grep "X11UseLocalhost" /etc/ssh/sshd_config 264 | 265 | echo "=== Linux > Access control > SSH reads environment from user file"=== 266 | grep "PermitUserEnvironment" /etc/ssh/sshd_config 267 | 268 | echo "=== Linux > Access control > SSH accepts environment variables"=== 269 | grep "AcceptEnv" /etc/ssh/sshd_config 270 | 271 | echo "=== Linux > Access control > SSH looks up connections in DNS"=== 272 | grep "UseDNS" /etc/ssh/sshd_config 273 | 274 | echo "=== Linux > Access control > SSH uses privilege separation"=== 275 | grep "UsePrivilegeSeparation" /etc/ssh/sshd_config 276 | 277 | echo "=== Linux > Access control > .shosts used"=== 278 | find / -name .shosts -ls 279 | 280 | echo "=== Linux > Access control > shosts.equiv used"=== 281 | cat /etc/shosts.equiv 282 | 283 | echo "=== Linux > Access control > SSH allows .rhosts"=== 284 | grep "IgnoreRhosts" /etc/ssh/sshd_config 285 | 286 | echo "=== Linux > Access control > SSH public/private keys used"=== 287 | find / \( -name id_dsa -o -name id_dsa.pub -o -name id_rsa -o -name id_rsa.pub -o -name authorized_keys \) | while read file 288 | do 289 | ls -l $file 290 | cat $file 291 | done 292 | 293 | echo "=== Linux > Access control > SSH sessions are throttled"=== 294 | egrep "MaxAuthTries|MaxSessions|MaxStartups" /etc/ssh/sshd_config 295 | 296 | echo "=== Linux > Access control > FTP users disallowed"=== 297 | cat /etc/ftpusers 298 | 299 | echo "=== Linux > Access control > NFS shares"=== 300 | cat /etc/exports 301 | 302 | echo "=== Linux > Access control > SMB shares"=== 303 | cat /etc/samba/smb.conf 304 | 305 | echo "=== Linux > Access control > Secure consoles"=== 306 | cat /etc/securetty 307 | 308 | echo "=== Linux > Authentication > Banner"=== 309 | cat /etc/issue 310 | 311 | echo "=== Linux > Authentication > MOTD"=== 312 | cat /etc/motd 313 | 314 | echo "=== Linux > Authentication > Passwords"=== 315 | cat /etc/passwd 316 | cat /etc/shadow 317 | 318 | echo "=== Linux > Authentication > Active Directory enabled"=== 319 | ps -aef | grep "vasd|sssd|pbis|slapd|adclient" 320 | 321 | echo "=== Linux > Authentication > Non-local users"=== 322 | getent passwd 323 | getent group 324 | 325 | echo "=== Linux > Authentication > Using NIS"=== 326 | ypcat passwd 327 | 328 | echo "=== Linux > Authentication > Using Kerberos"=== 329 | for file in /tmp/krb5* 330 | do 331 | ls -l $file 332 | done 333 | 334 | echo "=== Linux > Authentication > Using LDAP"=== 335 | cat /etc/ldap/ldap.conf 336 | 337 | echo "=== Linux > Authentication > SNMP community strings"=== 338 | grep community /etc/snmp/snmpd.conf 339 | 340 | echo "=== Linux > Authentication > System Auth PAM"=== 341 | grep "limits" /etc/pam.d/* 342 | grep "crack" /etc/pam.d/* 343 | grep "nullok" /etc/pam.d/* 344 | grep "md5" /etc/pam.d/* 345 | grep "shadow" /etc/pam.d/* 346 | grep "cap" /etc/pam.d/* 347 | 348 | echo "=== Linux > Authentication > Login PAM"=== 349 | grep "nologin" /etc/pam.d/* 350 | grep "securetty" /etc/pam.d/* 351 | grep "limits" /etc/pam.d/* 352 | grep "cap" /etc/pam.d/* 353 | 354 | echo "=== Linux > Authentication > Su PAM"=== 355 | grep "nologin" /etc/pam.d/* 356 | grep "securetty" /etc/pam.d/* 357 | grep "limits" /etc/pam.d/* 358 | grep "wheel" /etc/pam.d/* 359 | grep "cap" /etc/pam.d/* 360 | 361 | echo "=== Linux > Authentication > Sudo PAM"=== 362 | grep "nologin" /etc/pam.d/* 363 | grep "securetty" /etc/pam.d/* 364 | grep "limits" /etc/pam.d/* 365 | grep "wheel" /etc/pam.d/* 366 | grep "cap" /etc/pam.d/* 367 | 368 | echo "=== Linux > Authentication > Password aging"=== 369 | grep "MAX_DAYS" /etc/login.defs 370 | grep "MIN_DAYS" /etc/login.defs 371 | 372 | echo "=== Linux > Authentication > Password minimum strength"=== 373 | grep "MIN_LEN" /etc/login.defs 374 | 375 | echo "=== Linux > Authentication > Unlocked accounts"=== 376 | grep -v "!!" /etc/shadow 377 | 378 | echo "=== Linux > Authentication > Session timeout"=== 379 | echo $TMOUT 380 | 381 | echo "=== Linux > Authentication > SSH shows banner"=== 382 | grep "Banner" /etc/ssh/sshd_config 383 | 384 | echo "=== Linux > Authentication > SSH shows MOTD"=== 385 | grep "PrintMotd" /etc/ssh/sshd_config 386 | 387 | echo "=== Linux > Authentication > SSH uses PAM"=== 388 | grep "UsePAM" /etc/ssh/sshd_config 389 | 390 | echo "=== Linux > Authentication > SSH allows empty passwords"=== 391 | grep "PermitEmptyPasswords" /etc/ssh/sshd_config 392 | 393 | echo "=== Linux > Cryptography > known_hosts encrypted"=== 394 | find / -name known_hosts | while read file 395 | do 396 | ls -l $file 397 | cat $file 398 | done 399 | 400 | echo "=== Linux > Cryptography > SSH protocol"=== 401 | grep "Protocol" /etc/ssh/sshd_config 402 | 403 | echo "=== Linux > Cryptography > SSH protocol 1 key regeneration"=== 404 | grep "KeyRegenerationInterval" /etc/ssh/sshd_config 405 | 406 | echo "=== Linux > Cryptography > SSH protocol 1 key size"=== 407 | grep "ServerKeyBits" /etc/ssh/sshd_config 408 | 409 | echo "=== Linux > Cryptography > SSH protocol 2 public key authentication"=== 410 | grep "PubkeyAuthentication" /etc/ssh/sshd_config 411 | 412 | echo "=== Linux > Cryptography > SSH allows .rhosts with protocol 1 RSA"=== 413 | grep "RhostsRSAAuthentication" /etc/ssh/sshd_config 414 | 415 | echo "=== Linux > Cryptography > SSH allows protocol 1 RSA"=== 416 | grep "RSAAuthentication" /etc/ssh/sshd_config 417 | 418 | echo "=== Linux > Cryptography > SSH password based authentication"=== 419 | grep "PasswordAuthentication" /etc/ssh/sshd_config 420 | 421 | echo "=== Linux > Cryptography > SSH ciphers"=== 422 | grep "Ciphers" /etc/ssh/sshd_config 423 | 424 | echo "=== Linux > Cryptography > SSH MACs"=== 425 | grep "MACs" /etc/ssh/sshd_config 426 | 427 | echo "=== Linux > Cryptography > Blacklisted keys"=== 428 | grep "PermitBlacklistedKeys" /etc/ssh/sshd_config 429 | 430 | echo "=== Linux > Cryptography > Grub password obfuscated"=== 431 | grep "password" /boot/grub/menu.lst | grep "md5" 432 | 433 | echo "=== Linux > Cryptography > Crypto used for shadow"=== 434 | egrep "MD5_CRYPT_ENAB|ENCRYPT_METHOD" /etc/login.defs 435 | 436 | echo "=== Linux > Cryptography > Trusted CAs"=== 437 | md5sum /etc/ssl/certs/* 438 | 439 | echo "=== Linux > Cryptography > Trusted keyrings"=== 440 | md5sum /etc/apt/trusted.gpg.d/* 441 | md5sum /etc/pki/rpm-gpg/* 442 | 443 | echo "=== Linux > Software installed > OS release"=== 444 | cat /etc/*-release /etc/debian_version 445 | 446 | echo "=== Linux > Software installed > Packages installed"=== 447 | rpm -q -a 448 | dpkg --list --no-pager 449 | 450 | echo "=== Linux > Software installed > Packages for NOPC"=== 451 | rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}|%{EPOCH}\n' 452 | dpkg -l --no-pager 453 | 454 | echo "=== Linux > Software installed > Package management"=== 455 | cat /etc/apt/apt.conf 456 | for file in /etc/apt/apt.conf /etc/apt/apt.conf.d/* /etc/apt/sources.list /etc/apt/sources.list.d/* /etc/yum.conf /etc/yum.repos.d/*.repo /etc/dnf/dnf.conf 457 | do 458 | ls -l $file 459 | cat $file 460 | done 461 | 462 | echo "=== Linux > Software installed > Processes"=== 463 | ps -aef 464 | 465 | echo "=== Linux > Software installed > Services"=== 466 | chkconfig --list 467 | 468 | echo "=== Linux > Software installed > Systemd services"=== 469 | systemctl --no-pager 470 | 471 | echo "=== Linux > Software installed > Systemd configs"=== 472 | find /usr/lib/systemd/* /etc/systemd/* -type f | while read file 473 | do 474 | ls -l $file 475 | cat $file 476 | done 477 | 478 | echo "=== Linux > Software installed > Development tools"=== 479 | find / -type f \( -name perl -o -name gcc -o -name javac -o -name python -o -name ruby -o -name gdb \) -ls 480 | 481 | echo "=== Linux > Software installed > 3rd party software"=== 482 | find /usr/local -ls 483 | find /opt -ls 484 | 485 | echo "=== Linux > Logging > Time synchronisation"=== 486 | ps -aef | grep "ntp" 487 | 488 | echo "=== Linux > Logging > Syslog process"=== 489 | ps -aef | grep syslog 490 | 491 | echo "=== Linux > Logging > Remote logging"=== 492 | grep "@" /etc/syslog.conf 493 | 494 | echo "=== Linux > Logging > Syslog with rsyslog"=== 495 | for file in /etc/rsyslog.conf /etc/rsyslog.d/* 496 | do 497 | ls -l $file 498 | cat $file 499 | done 500 | 501 | echo "=== Linux > Logging > Syslog with syslog-ng"=== 502 | cat /etc/syslog-ng/syslog-ng.conf 503 | 504 | echo "=== Linux > Logging > Cron logging"=== 505 | grep "cron" /etc/syslog.conf 506 | 507 | echo "=== Linux > Logging > User histories"=== 508 | find /home \( -name .sh_history -o -name .bash_history \) | while read file 509 | do 510 | ls -l $file 511 | cat $file 512 | done 513 | 514 | echo "=== Linux > Logging > Auditing"=== 515 | ps -aef | grep auditd 516 | auditctl -s 517 | 518 | echo "=== Linux > Logging > Auditd policy"=== 519 | for file in /etc/audit/audit.rules /etc/audit/audit.rules.d/* 520 | do 521 | ls -l $file 522 | cat $file 523 | done 524 | 525 | echo "=== Linux > Resource limits > Configured limits"=== 526 | cat /etc/security/limits.conf 527 | 528 | echo "=== Linux > Resource limits > Running limits"=== 529 | ulimit -a 530 | 531 | echo "=== Linux > Resource limits > Tmp size"=== 532 | mount | grep "/tmp" | grep "size" 533 | 534 | echo "=== Linux > Resource limits > Disk quotas"=== 535 | mount | grep "quota" 536 | 537 | echo "=== Linux > File permissions > Init umask"=== 538 | grep "umask" /etc/rc.d/init.d/functions 539 | 540 | echo "=== Linux > File permissions > Syslog umask"=== 541 | grep "umask" /etc/rc.d/init.d/syslog /etc/sysconfig/syslog 542 | 543 | echo "=== Linux > File permissions > Root umask"=== 544 | umask 545 | 546 | echo "=== Linux > File permissions > User umask"=== 547 | grep "UMASK" /etc/login.defs 548 | grep "umask" /home/*/.[a-z]* 549 | 550 | echo "=== Linux > File permissions > Service umasks"=== 551 | grep "umask" /etc/rc.d/rc*.d/* 552 | 553 | echo "=== Linux > File permissions > World readable files / directories"=== 554 | find / -perm -o+r -ls 555 | 556 | echo "=== Linux > File permissions > World writable files / directories"=== 557 | find / -perm -o+w -ls 558 | 559 | echo "=== Linux > File permissions > Group writable files / directories"=== 560 | find / -perm -o+w -ls 561 | 562 | echo "=== Linux > File permissions > Unowned files / directories"=== 563 | find / -nouser -ls 564 | 565 | echo "=== Linux > File permissions > Ungrouped files / directories"=== 566 | find / -nogroup -ls 567 | 568 | echo "=== Linux > File permissions > Log files"=== 569 | ls -la /var/log 570 | 571 | echo "=== Linux > File permissions > SSH strict mode"=== 572 | grep "StrictModes" /etc/ssh/sshd_config 573 | 574 | echo "=== Linux > File permissions > Root home"=== 575 | find /root -ls 576 | 577 | echo "=== Linux > File permissions > User homes"=== 578 | ls -la /home/* 579 | 580 | echo "=== Linux > Exploit mitigation > Active mounts secure"=== 581 | mount | grep -v "nosetuid" 582 | mount | grep -v "noexec" 583 | 584 | echo "=== Linux > Exploit mitigation > Configured mounts secure"=== 585 | grep -v "nosetuid" /etc/fstab 586 | grep -v "noexec" /etc/fstab 587 | 588 | echo "=== Linux > Exploit mitigation > Separate partitions"=== 589 | mount | grep "/var" 590 | mount | grep "/var/log" 591 | mount | grep "/home" 592 | 593 | echo "=== Linux > Exploit mitigation > SELinux supported"=== 594 | grep "SELINUX=" /etc/selinux/config 595 | 596 | echo "=== Linux > Exploit mitigation > SELinux policy"=== 597 | grep "SELINUXTYPE=" /etc/selinux/config 598 | 599 | echo "=== Linux > Exploit mitigation > SELinux running"=== 600 | selinux -v 601 | 602 | echo "=== Linux > Exploit mitigation > SELinux processes"=== 603 | ps -aefZ 604 | 605 | echo "=== Linux > Exploit mitigation > AppArmour supported"=== 606 | cat /sys/module/apparmor/parameters/enabled 607 | 608 | echo "=== Linux > Exploit mitigation > AppArmour policy"=== 609 | aa-status 610 | 611 | echo "=== Linux > Exploit mitigation > AppArmour processes"=== 612 | aa-unconfined 613 | ps -aefZ 614 | 615 | echo "=== Linux > Exploit mitigation > Cron users"=== 616 | cat /etc/cron.allow /etc/cron.deny 617 | 618 | echo "=== Linux > Exploit mitigation > At users"=== 619 | cat /etc/at.allow /etc/at.deny 620 | 621 | echo "=== Linux > Exploit mitigation > Stack randomisation"=== 622 | sysctl kernel.randomize_va_space 623 | 624 | echo "=== Linux > Exploit mitigation > Non executable stack"=== 625 | grep "stack" /proc/[0-9]*/maps 626 | 627 | echo "=== Linux > Exploit mitigation > Stack smashing protection"=== 628 | for x in /proc/[0-9]* 629 | do 630 | ls -l $x/exe | sed "s/.* -> //g" 631 | objdump -D $x/exe | grep stack_chk | sort | uniq 632 | done 633 | find / \( -perm -u+s -o -perm -g+s \) | while read file 634 | do 635 | ls -l $file 636 | objdump -D $file | grep "stack_chk" | sort | uniq 637 | done 638 | 639 | echo "=== Linux > Exploit mitigation > SetUID debug"=== 640 | ls -l /etc/suid-debug 641 | 642 | echo "=== Linux > Exploit mitigation > PTrace scope"=== 643 | sysctl -a | grep "ptrace_scope" 644 | 645 | echo "=== Linux > Privilege escalation > User capabilities"=== 646 | ls -l /etc/security/capability.conf 647 | cat /etc/security/capability.conf 648 | 649 | echo "=== Linux > Privilege escalation > Init scripts run"=== 650 | for file in /etc/rc.d/*.d/* 651 | do 652 | ls -l $file 653 | cat $file 654 | done 655 | 656 | echo "=== Linux > Privilege escalation > At scripts run"=== 657 | for file in /var/spool/atjobs/* 658 | do 659 | ls -l $file 660 | cat $file 661 | done 662 | 663 | echo "=== Linux > Privilege escalation > Cron scripts run"=== 664 | for file in /etc/crontab /var/spool/crontabs/* /etc/cron.d/* /etc/cron.daily/* /etc/cron.weekly/* /etc/cron.monthly/* /etc/cron.hourly/* 665 | do 666 | ls -l $file 667 | cat $file 668 | done 669 | 670 | echo "=== Linux > Privilege escalation > Default path"=== 671 | echo $PATH 672 | 673 | echo "=== Linux > Privilege escalation > User paths"=== 674 | for file in /etc/profile /etc/bash.bashrc /home/*/.[a-z]* 675 | do 676 | ls -l $file 677 | grep "PATH" $file 678 | done 679 | 680 | echo "=== Linux > Privilege escalation > Init paths"=== 681 | for file in /etc/rc.d/init.d/* 682 | do 683 | ls -l $file 684 | grep "PATH" $file 685 | done 686 | 687 | echo "=== Linux > Privilege escalation > Default linker path"=== 688 | for file in /etc/ld.so.conf /etc/ld.so.conf.d/* 689 | do 690 | ls -l $file 691 | cat $file 692 | done 693 | 694 | echo "=== Linux > Privilege escalation > User linker paths"=== 695 | for file in /etc/profile /etc/bash.bashrc /home/*/.[a-z]* 696 | do 697 | ls -l $file 698 | grep "LD_LIBRARY_PATH" $file 699 | done 700 | 701 | echo "=== Linux > Privilege escalation > Init linker paths"=== 702 | for file in /etc/rc.d/init.d/* 703 | do 704 | ls -l $file 705 | grep "LD_LIBRARY_PATH" $file 706 | done 707 | 708 | echo "=== Linux > Privilege escalation > SetUID files"=== 709 | find / -perm -u+s -type f -ls 710 | 711 | echo "=== Linux > Privilege escalation > SetGID files"=== 712 | find / -perm -g+s -type f -ls 713 | 714 | echo "=== Linux > Privilege escalation > Sudo configuration"=== 715 | for file in /etc/sudoers /etc/sudoers.d/* 716 | do 717 | ls -l $file 718 | cat $file 719 | done 720 | 721 | echo "=== Linux > Privilege escalation > Insecure RPATHs"=== 722 | find / \( -perm -o+s -o -g+s \) | while read file 723 | do 724 | ls -l $file 725 | objdump -x $file | egrep "RPATH|RUNPATH" 726 | done 727 | 728 | echo "=== Linux > Privilege escalation > Processes with open files"=== 729 | lsof 730 | 731 | echo "=== Linux > Privilege escalation > Proc tree"=== 732 | find /proc -type f | while read file 733 | do 734 | ls -l $file 735 | strings $file 736 | done 737 | 738 | echo "=== Linux > Privilege escalation > Sys tree"=== 739 | find /sys -type f | while read file 740 | do 741 | ls -l $file 742 | strings $file 743 | done 744 | 745 | echo "=== Linux > Privilege escalation > POSIX shared memory"=== 746 | ls -la /dev/shm 747 | 748 | echo "=== Linux > Privilege escalation > System V shared memory"=== 749 | ipcs -a 750 | 751 | echo "=== Linux > Privilege escalation > UNIX sockets"=== 752 | find / -type s -ls 753 | 754 | echo "=== Linux > Common services > SSH config"=== 755 | cat /etc/ssh/sshd_config 756 | 757 | echo "=== Linux > Common services > SSH client config"=== 758 | cat /etc/ssh/ssh_config 759 | 760 | echo "=== Linux > Common services > SSH running config"=== 761 | sshd -T 762 | 763 | echo "=== Linux > Common services > Web server config"=== 764 | find / -name httpd.conf | while read file 765 | do 766 | ls -l $file 767 | cat $file 768 | done 769 | 770 | echo "=== Linux > Common services > Web server logs"=== 771 | find / -name access.log | while read file 772 | do 773 | ls -l $file 774 | grep -i "curl|wget|python|perl" $file 775 | done 776 | 777 | echo "=== Linux > Common services > Web server cgi-bin"=== 778 | find / -name cgi-bin | while read file 779 | do 780 | ls -l $file 781 | done 782 | 783 | echo "=== Linux > Important file locations > Configs"=== 784 | tar cvf etc-`hostname`.tar /etc 785 | gzip etc-`hostname`.tar 786 | 787 | echo "=== Linux > Important file locations > Logs"=== 788 | tar cvf logs-`hostname`.tar /var/log 789 | gzip logs-`hostname`.tar 790 | 791 | echo "=== Linux > Important file locations > SetUID and setGIDs files"=== 792 | tar cvf suids-`hostname`.tar `find / \( -perm -o+s -o -perm -g+s \)` 793 | gzip suids-`hostname`.tar 794 | 795 | echo "=== Linux > Important file locations > Temporary locations"=== 796 | tar cvf tmp-`hostname`.tar /tmp /var/tmp /dev/shm /dev/mqueue /run/screen /run/lock /var/crash 797 | gzip tmp-`hostname`.tar 798 | 799 | echo "=== Linux > Important file locations > Core files"=== 800 | tar cvf core-`hostname`.tar `find / -type f \( -name core -o -name core.[0-9]* \)` 801 | gzip core-`hostname`.tar 802 | 803 | 804 | -------------------------------------------------------------------------------- /audit-scripts/solaris-audit.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2020, Tim Brown 2 | # Copyright Ciso Systems, Inc. and its affiliates 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the Cisco International Ltd nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CISCO INTERNATIONAL LTD BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | echo "=== Solaris > Informational > Hostname"=== 27 | cat /etc/nodename 28 | 29 | echo "=== Solaris > Informational > Kernel version"=== 30 | uname -a 31 | 32 | echo "=== Solaris > Informational > Network interfaces"=== 33 | ifconfig -a 34 | 35 | echo "=== Solaris > Environment > PCI cards accessible"=== 36 | prtconf -v 37 | 38 | echo "=== Solaris > Environment > USB peripherals accessible"=== 39 | prtconf -v 40 | 41 | echo "=== Solaris > Environment > Loaded kernel modules"=== 42 | modinfo 43 | 44 | echo "=== Solaris > Environment > OBP password set"=== 45 | eeprom | grep "security-mode" 46 | 47 | echo "=== Solaris > Environment > OBP banner set"=== 48 | eeprom | grep "oem-banner" 49 | 50 | echo "=== Solaris > Environment > Grub password set"=== 51 | /sbin/bootadm list-menu 52 | grep password "/path/to/menu.lst" 53 | 54 | echo "=== Solaris > Environment > Stop-A"=== 55 | grep "abort_enable" /etc/system 56 | 57 | echo "=== Solaris > Environment > Zones"=== 58 | zoneadm list 59 | 60 | echo "=== Solaris > Networking > ARP"=== 61 | arp -a 62 | cat /etc/ethers 63 | 64 | echo "=== Solaris > Networking > Routing"=== 65 | netstat -rn 66 | cat /etc/defaultrouter 67 | 68 | echo "=== Solaris > Networking > Name services"=== 69 | cat /etc/nsswitch.conf 70 | 71 | echo "=== Solaris > Networking > Hosts"=== 72 | cat /etc/hosts 73 | 74 | echo "=== Solaris > Networking > DNS"=== 75 | cat /etc/resolv.conf 76 | 77 | echo "=== Solaris > Networking > Internet"=== 78 | ping -c 5 www.google.co.uk 79 | ping -c 5 8.8.8.8 80 | 81 | echo "=== Solaris > Networking > Listening services"=== 82 | netstat -an | egrep "LISTEN|TCP|UDP" 83 | netstat -aun | egrep "LISTEN|TCP|UDP" 84 | 85 | echo "=== Solaris > Networking > IPv6"=== 86 | ifconfig lo | grep "::1" 87 | ls /etc/hostname6.* 88 | 89 | echo "=== Solaris > Network stack tuning > IP forwarding"=== 90 | cat /etc/notrouter 91 | ndd /dev/ip ip_forwarding 92 | ndd /dev/ip ip6_forwarding 93 | 94 | echo "=== Solaris > Network stack tuning > Source routing"=== 95 | ndd /dev/ip ip_forward_src_routed 96 | ndd /dev/ip ip6_forward_src_routed 97 | 98 | echo "=== Solaris > Network stack tuning > Directed broadcasts"=== 99 | ndd /dev/ip ip_forward_directed_broadcasts 100 | ndd /dev/ip ip6_forward_directed_broadcasts 101 | 102 | echo "=== Solaris > Network stack tuning > Echo broadcasts"=== 103 | ndd /dev/ip ip_respond_to_echo_broadcasts 104 | ndd /dev/ip ip_respond_to_echo_multicast 105 | ndd /dev/ip ip6_respond_to_echo_multicast 106 | 107 | echo "=== Solaris > Network stack tuning > Timestamp broadcasts"=== 108 | ndd /dev/ip ip_respond_to_timestamp 109 | ndd /dev/ip ip_respond_to_timestamp_broadcast 110 | 111 | echo "=== Solaris > Network stack tuning > Redirects"=== 112 | ndd /dev/ip ip_ignore_redirect 113 | ndd /dev/ip ip6_ignore_redirect 114 | 115 | echo "=== Solaris > Network stack tuning > Netmask broadcasts"=== 116 | ndd /dev/ip ip_respond_to_address_mask_broadcast 117 | 118 | echo "=== Solaris > Network stack tuning > TCP limits"=== 119 | ndd /dev/tcp tcp_conn_req_max_q 120 | ndd /dev/tcp tcp_conn_req_max_q0 121 | 122 | echo "=== Solaris > Network stack tuning > Strict multihoming"=== 123 | ndd /dev/ip ip_strict_dst_multihoming 124 | ndd /dev/ip ip6_strict_dst_multihoming 125 | 126 | echo "=== Solaris > Network stack tuning > Strong ISS"=== 127 | grep "TCP_STRONG_ISS" /etc/default/inetinit 128 | ndd /dev/tcp tcp_strong_iss 129 | 130 | echo "=== Solaris > Network stack tuning > Generic tuning - we should break this down and cross reference OS"=== 131 | for device in arp ip ip6 rawip rawip6 sockets tcp udp 132 | do 133 | echo "Device: $device" 134 | ndd /dev/$device '?' | grep -v '?' | while read parameter _ 135 | do 136 | echo "Parameter: $parameter" 137 | ndd /dev/$device $parameter 138 | done 139 | done 140 | 141 | echo "=== Solaris > Access control > Firewall configured"=== 142 | cat /etc/ipf/ipf.conf 143 | 144 | echo "=== Solaris > Access control > TCP wrappers used"=== 145 | cat /etc/hosts.allow 146 | cat /etc/hosts.deny 147 | 148 | echo "=== Solaris > Access control > .rhosts used"=== 149 | find / -name .rhosts -ls 150 | 151 | echo "=== Solaris > Access control > hosts.equiv used"=== 152 | cat /etc/hosts.equiv 153 | 154 | echo "=== Solaris > Access control > .netrc used"=== 155 | find / -name .netrc -ls 156 | 157 | echo "=== Solaris > Access control > Remote X"=== 158 | netstat -an | grep "LISTEN" | egrep "6000|177" 159 | 160 | echo "=== Solaris > Access control > Accounts with non-standard shells"=== 161 | grep -v "/bash$" /etc/passwd 162 | 163 | echo "=== Solaris > Access control > Valid shells"=== 164 | cat /etc/shells 165 | 166 | echo "=== Solaris > Access control > SSH ACLs configured"=== 167 | grep "Match" /etc/ssh/sshd_config 168 | 169 | echo "=== Solaris > Access control > SSH user logins"=== 170 | egrep "AllowUsers|DenyUsers|AllowGroups|DenyGroups" /etc/ssh/sshd_config 171 | 172 | echo "=== Solaris > Access control > SSH root logins"=== 173 | grep "PermitRootLogin" /etc/ssh/sshd_config 174 | 175 | echo "=== Solaris > Access control > SSH TCP forwarding"=== 176 | grep "AllowTcpForwarding" /etc/ssh/sshd_config 177 | 178 | echo "=== Solaris > Access control > SSH gateway ports"=== 179 | grep "GatewayPorts" /etc/ssh/sshd_config 180 | 181 | echo "=== Solaris > Access control > SSH VPN"=== 182 | grep "PermitTunnel" /etc/ssh/sshd_config 183 | 184 | echo "=== Solaris > Access control > SSH agent forwarding"=== 185 | grep "AllowAgentForwarding" /etc/ssh/sshd_config 186 | 187 | echo "=== Solaris > Access control > SSH X11 forwarding"=== 188 | grep "X11Forwarding" /etc/ssh/sshd_config 189 | 190 | echo "=== Solaris > Access control > SSH binds X11 to localhost"=== 191 | grep "X11UseLocalhost" /etc/ssh/sshd_config 192 | 193 | echo "=== Solaris > Access control > SSH reads environment from user file"=== 194 | grep "PermitUserEnvironment" /etc/ssh/sshd_config 195 | 196 | echo "=== Solaris > Access control > SSH accepts environment variables"=== 197 | grep "AcceptEnv" /etc/ssh/sshd_config 198 | 199 | echo "=== Solaris > Access control > SSH looks up connections in DNS"=== 200 | grep "UseDNS" /etc/ssh/sshd_config 201 | 202 | echo "=== Solaris > Access control > SSH uses privilege separation"=== 203 | grep "UsePrivilegeSeparation" /etc/ssh/sshd_config 204 | 205 | echo "=== Solaris > Access control > .shosts used"=== 206 | find / -name .shosts -ls 207 | 208 | echo "=== Solaris > Access control > shosts.equiv used"=== 209 | cat /etc/shosts.equiv 210 | 211 | echo "=== Solaris > Access control > SSH allows .rhosts"=== 212 | grep "IgnoreRhosts" /etc/ssh/sshd_config 213 | 214 | echo "=== Solaris > Access control > SSH public/private keys used"=== 215 | find / -name .ssh -type d -exec ls -la {} \; 216 | 217 | echo "=== Solaris > Access control > SSH sessions are throttled"=== 218 | grep "MaxStartups" /etc/ssh/sshd_config 219 | 220 | echo "=== Solaris > Access control > FTP users disallowed"=== 221 | cat /etc/ftpd/ftpusers 222 | 223 | echo "=== Solaris > Access control > NFS shares"=== 224 | cat /etc/dfs/sharetab 225 | share -A 226 | 227 | echo "=== Solaris > Access control > Secure consoles"=== 228 | grep "CONSOLE" /etc/default/login 229 | 230 | echo "=== Solaris > Authentication > Banner"=== 231 | cat /etc/issue 232 | 233 | echo "=== Solaris > Authentication > MOTD"=== 234 | cat /etc/motd 235 | 236 | echo "=== Solaris > Authentication > Passwords"=== 237 | cat /etc/passwd 238 | cat /etc/shadow 239 | passwd -a -s | grep "NP" 240 | 241 | echo "=== Solaris > Authentication > SNMP community strings"=== 242 | grep "community" /etc/snmp/conf/snmpd.conf 243 | grep "community" /etc/net-snmp/conf/snmpd.conf 244 | 245 | echo "=== Solaris > Authentication > Login policy"=== 246 | cat /etc/default/login 247 | 248 | echo "=== Solaris > Authentication > Password aging"=== 249 | grep "WEEKS" /etc/default/passwd 250 | 251 | echo "=== Solaris > Authentication > Password minimum strength"=== 252 | cat /etc/default/passwd 253 | 254 | echo "=== Solaris > Authentication > Unlocked accounts"=== 255 | passwd -a -s | egrep -v "LK|NL" 256 | 257 | echo "=== Solaris > Authentication > Lock after retries"=== 258 | grep "LOCK_AFTER_RETRIES" /etc/security/policy.conf 259 | grep "RETRIES" /etc/default/login 260 | 261 | echo "=== Solaris > Authentication > Session timeout"=== 262 | grep "TMOUT" /etc/profile 263 | 264 | echo "=== Solaris > Authentication > SSH shows banner"=== 265 | grep "Banner" /etc/ssh/sshd_config 266 | 267 | echo "=== Solaris > Authentication > SSH shows MOTD"=== 268 | grep "PrintMotd" /etc/ssh/sshd_config 269 | 270 | echo "=== Solaris > Authentication > SSH allows empty passwords"=== 271 | grep "PermitEmptyPasswords" /etc/ssh/sshd_config 272 | 273 | echo "=== Solaris > Cryptography > known_hosts encrypted"=== 274 | grep "HashKnownHosts" /etc/ssh/ssh_config 275 | 276 | echo "=== Solaris > Cryptography > SSH protocol"=== 277 | grep "Protocol" /etc/ssh/sshd_config 278 | 279 | echo "=== Solaris > Cryptography > SSH protocol 1 key regeneration"=== 280 | grep "KeyRegenerationInterval" /etc/ssh/sshd_config 281 | 282 | echo "=== Solaris > Cryptography > SSH protocol 1 key size"=== 283 | grep "ServerKeyBits" /etc/ssh/sshd_config 284 | 285 | echo "=== Solaris > Cryptography > SSH protocol 2 public key authentication"=== 286 | grep "PubkeyAuthentication" /etc/ssh/sshd_config 287 | 288 | echo "=== Solaris > Cryptography > SSH allows .rhosts with protocol 1 RSA"=== 289 | grep "RhostsRSAAuthentication" /etc/ssh/sshd_config 290 | 291 | echo "=== Solaris > Cryptography > SSH allows protocol 1 RSA"=== 292 | grep "RSAAuthentication" /etc/ssh/sshd_config 293 | 294 | echo "=== Solaris > Cryptography > SSH password based authentication"=== 295 | grep "PasswordAuthentication" /etc/ssh/sshd_config 296 | 297 | echo "=== Solaris > Cryptography > SSH ciphers"=== 298 | grep "Ciphers" /etc/ssh/sshd_config 299 | 300 | echo "=== Solaris > Cryptography > SSH MACs"=== 301 | grep "MACs" /etc/ssh/sshd_config 302 | 303 | echo "=== Solaris > Cryptography > Blacklisted keys"=== 304 | grep "PermitBlacklistedKeys" /etc/ssh/sshd_config 305 | 306 | echo "=== Solaris > Cryptography > Grub password obfuscated"=== 307 | grep "password" /path/to/menu.lst | grep "md5" 308 | 309 | echo "=== Solaris > Cryptography > Crypto used for shadow"=== 310 | grep "CRYPT_DEFAULT" /etc/security/policy.conf 311 | 312 | echo "=== Solaris > Cryptography > Crypto allowed for shadow"=== 313 | grep "CRYPT_ALGORITHMS_ALLOW" /etc/security/policy.conf 314 | 315 | echo "=== Solaris > Software installed > OS release"=== 316 | uname -r 317 | 318 | echo "=== Solaris > Software installed > Packages installed"=== 319 | pkginfo 320 | pkg list 321 | 322 | echo "=== Solaris > Software installed > Packages legit"=== 323 | pkg verify 324 | 325 | echo "=== Solaris > Software installed > Patches installed"=== 326 | showrev -p 327 | smpatch analyze 328 | 329 | echo "=== Solaris > Software installed > Processes"=== 330 | ps -aef 331 | 332 | echo "=== Solaris > Software installed > Services"=== 333 | svcs 334 | 335 | echo "=== Solaris > Software installed > Development tools"=== 336 | find / -type f \( -name perl -o -name gcc -o -name javac -o -name python -o -name ruby -o -name cc -o -name gdb -o -name mdb \) 337 | 338 | echo "=== Solaris > Software installed > 3rd party software"=== 339 | find /usr/local /opt -type f -ls 340 | 341 | echo "=== Solaris > Logging > Time synchronisation"=== 342 | grep "server" /etc/inet/ntp.conf 343 | 344 | echo "=== Solaris > Logging > Remote logging"=== 345 | grep "@" /etc/syslog.conf 346 | 347 | echo "=== Solaris > Logging > Cron logging"=== 348 | grep "CRONLOG" /etc/default/cron 349 | 350 | echo "=== Solaris > Logging > Auditing"=== 351 | ps -aef | grep "auditd" 352 | 353 | echo "=== Solaris > Resource limits > Running limits"=== 354 | ulimit -a 355 | 356 | echo "=== Solaris > Resource limits > Tmp size"=== 357 | grep "swap" /etc/vfstab | grep "size" 358 | 359 | echo "=== Solaris > Resource limits > Disk quotas"=== 360 | mount | grep "quota" 361 | 362 | echo "=== Solaris > File permissions > Init umask"=== 363 | grep "CMASK" /etc/default/init 364 | 365 | echo "=== Solaris > File permissions > Root umask"=== 366 | grep "umask" /root/.profile 367 | 368 | echo "=== Solaris > File permissions > User umask"=== 369 | grep "umask" /etc/profile 370 | 371 | echo "=== Solaris > File permissions > Service umasks"=== 372 | grep "umask" /etc/init.d/* /etc/rc*.d/* 373 | 374 | echo "=== Solaris > File permissions > World readable files / directories"=== 375 | find / -perm -o+r -ls 376 | 377 | echo "=== Solaris > File permissions > World writable files / directories"=== 378 | find / -perm -o+w -ls 379 | 380 | echo "=== Solaris > File permissions > Group writable files / directories"=== 381 | find / -perm -o+w -ls 382 | 383 | echo "=== Solaris > File permissions > Unowned files / directories"=== 384 | find / -nouser -ls 385 | 386 | echo "=== Solaris > File permissions > Ungrouped files / directories"=== 387 | find / -nogroup -ls 388 | 389 | echo "=== Solaris > File permissions > Log files"=== 390 | ls -la /var/log /var/adm 391 | 392 | echo "=== Solaris > File permissions > SSH strict mode"=== 393 | grep "StrictModes" /etc/ssh/sshd_config 394 | 395 | echo "=== Solaris > File permissions > Root home"=== 396 | ls -ld `cat /etc/passwd | grep "root" | cut -f 6 -d ":"` 397 | ls -la /path/to/root 398 | 399 | echo "=== Solaris > File permissions > IPC"=== 400 | ipcs -A 401 | 402 | echo "=== Solaris > File permissions > Device policy"=== 403 | cat /etc/security/device_policy 404 | 405 | echo "=== Solaris > Exploit mitigation > Active mounts secure"=== 406 | mount | grep -v "noexec" 407 | mount | grep -v "nosetuid" 408 | mount | grep -v "nosuid" 409 | mount | grep -v "norstchown" 410 | 411 | echo "=== Solaris > Exploit mitigation > Configured mounts secure"=== 412 | grep -v "noexec" /etc/vfstab 413 | grep -v "nosetuid" /etc/vfstab 414 | grep -v "nosuid" /etc/vfstab 415 | grep -v "norstchown" /etc/vfstab 416 | 417 | echo "=== Solaris > Exploit mitigation > Separate partitions"=== 418 | mount 419 | 420 | echo "=== Solaris > Exploit mitigation > Cron users"=== 421 | cat /etc/cron.allow 422 | 423 | echo "=== Solaris > Exploit mitigation > At users"=== 424 | cat /etc/at.allow 425 | 426 | echo "=== Solaris > Exploit mitigation > Non executable stack"=== 427 | grep "noexec_user_stack" /etc/system 428 | 429 | echo "=== Solaris > Exploit mitigation > Stack randomisation"=== 430 | sxadm info 431 | 432 | echo "=== Solaris > Exploit mitigation > Randomised binaries"=== 433 | find / -type f \( -perm -u+s -o -perm -g+s \) | while read file 434 | do 435 | echo "File: $file" 436 | elfdump $file | grep "ASLR" 437 | done 438 | 439 | echo "=== Solaris > Exploit mitigation > Basic profile"=== 440 | grep "_GRANTED" /etc/security/policy.conf 441 | 442 | echo "=== Solaris > Exploit mitigation > Console profile"=== 443 | grep "CONSOLE_USER" /etc/security/policy.conf 444 | 445 | echo "=== Solaris > Exploit mitigation > Basic privs"=== 446 | grep "PRIV_DEFAULT" /etc/security/policy.conf 447 | 448 | echo "=== Solaris > Exploit mitigation > Priv limits"=== 449 | grep "PRIV_LIMIT" /etc/security/policy.conf 450 | 451 | echo "=== Solaris > Privilege escalation > Init scripts run"=== 452 | cat /etc/inittab 453 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 454 | do 455 | echo "File: $file" 456 | ls -la $file 457 | done 458 | 459 | echo "=== Solaris > Privilege escalation > At scripts run"=== 460 | for file in /var/spool/cron/atjobs/* 461 | do 462 | echo "File: $file" 463 | ls -l $file 464 | cat $file 465 | done 466 | 467 | echo "=== Solaris > Privilege escalation > Cron scripts run"=== 468 | for file in /var/spool/cron/crontabs/* 469 | do 470 | echo "File: $file" 471 | ls -l $file 472 | cat $file 473 | done 474 | 475 | echo "=== Solaris > Privilege escalation > Default path"=== 476 | grep "PATH" /etc/profile 477 | echo $PATH 478 | 479 | echo "=== Solaris > Privilege escalation > User paths"=== 480 | grep "PATH" /etc/skel/.profile 481 | echo $PATH 482 | 483 | echo "=== Solaris > Privilege escalation > Init paths"=== 484 | grep "PATH" /etc/init.d/* /etc/rc*.d 485 | 486 | echo "=== Solaris > Privilege escalation > Default linker path"=== 487 | grep "LD_LIBRARY_PATH" /etc/profile 488 | echo $LD_LIBRARY_PATH 489 | 490 | echo "=== Solaris > Privilege escalation > User linker paths"=== 491 | grep "LD_LIBRARY_PATH" /etc/skel/.profile 492 | 493 | echo "=== Solaris > Privilege escalation > Init linker paths"=== 494 | grep "LD_LIBRARY_PATH" /etc/init.d/* /etc/rc*.d 495 | 496 | echo "=== Solaris > Privilege escalation > SetUID files"=== 497 | find / -perm -u+s -type f -ls 498 | 499 | echo "=== Solaris > Privilege escalation > SetGID files"=== 500 | find / -perm -g+s -type f -ls 501 | 502 | echo "=== Solaris > Privilege escalation > Sudo configuration"=== 503 | cat /etc/sudoers 504 | for file in /etc/sudoers.d/* 505 | do 506 | echo "File: $file" 507 | cat $file 508 | done 509 | 510 | echo "=== Solaris > Privilege escalation > Roles"=== 511 | cat /etc/user_attr 512 | cat /etc/passwd | cut -f 1 -d ":" | while read user 513 | do 514 | echo "User: $user" 515 | roles $user 516 | done 517 | 518 | echo "=== Solaris > Privilege escalation > Profiles"=== 519 | cat /etc/security/prof_attr 520 | for file in /etc/security/prof_attr.d/* 521 | do 522 | echo "File: $file" 523 | cat $file 524 | done 525 | 526 | echo "=== Solaris > Privilege escalation > Command profiles"=== 527 | cat /etc/security/exec_attr 528 | for file in /etc/security/exec_attr.d/* 529 | do 530 | echo "File: $file" 531 | cat $file 532 | done 533 | 534 | echo "=== Solaris > Common services > SSH running config"=== 535 | sshd -T 536 | 537 | echo "=== Solaris > Common services > Web server config"=== 538 | find / -name httpd.conf | while read file 539 | do 540 | echo "File: $file" 541 | ls -l $file 542 | cat $file 543 | done 544 | 545 | echo "=== Solaris > Common services > Web server cgi-bin"=== 546 | find /usr/lib -name cgi-bin | while read file 547 | do 548 | echo "File: $file" 549 | ls -l $file 550 | done 551 | 552 | 553 | -------------------------------------------------------------------------------- /checks-database/aix.md: -------------------------------------------------------------------------------- 1 | # AIX 2 | PlatformTag: aix 3 | ## Informational 4 | Tags: informational 5 | ### Hostname 6 | ``` 7 | hostname 8 | ``` 9 | ### Kernel version 10 | ``` 11 | uname -a 12 | ``` 13 | ### Network interfaces 14 | ``` 15 | ifconfig -a 16 | ``` 17 | ## Environment 18 | Tags: environment 19 | ### PCI cards accessible 20 | ``` 21 | lsdev -C 22 | ``` 23 | ### USB peripherals accessible 24 | ``` 25 | lsdev -C 26 | ``` 27 | ## Networking 28 | Tags: networking 29 | ### ARP 30 | ``` 31 | arp -an 32 | ``` 33 | ### Routing 34 | ``` 35 | netstat -rn 36 | ``` 37 | ### Name services 38 | ``` 39 | cat /etc/netsvc.conf 40 | ``` 41 | ### Hosts 42 | ``` 43 | cat /etc/hosts 44 | ``` 45 | ### DNS 46 | ``` 47 | cat /etc/resolv.conf 48 | ``` 49 | ### Internet 50 | ``` 51 | ping -c 5 www.google.co.uk 52 | ping -c 5 8.8.8.8 53 | ``` 54 | ### Listening services 55 | ``` 56 | netstat -an | grep -v "unix" | grep "LISTEN" 57 | ``` 58 | ### IPv6 59 | ``` 60 | ifconfig lo0 | grep "::1" 61 | ``` 62 | ## Network stack tuning 63 | Tags: network-stack-tuning 64 | ### IP forwarding 65 | ``` 66 | /usr/sbin/no -a | grep "ipforwarding" 67 | ``` 68 | ## Access control 69 | Tags: access-control 70 | ### Firewall configured 71 | ``` 72 | lsfilt 73 | ``` 74 | ### TCP wrappers used 75 | ``` 76 | cat /etc/hosts.allow 77 | cat /etc/hosts.deny 78 | ``` 79 | ### .rhosts used 80 | ``` 81 | find / -name .rhosts -ls 82 | ``` 83 | ### hosts.equiv used 84 | ``` 85 | cat /etc/hosts.equiv 86 | ``` 87 | ### .netrc used 88 | ``` 89 | find / -name .netrc -ls 90 | ``` 91 | ### Remote X 92 | ``` 93 | netstat -an | grep "LISTEN" | egrep "6000|177" 94 | ``` 95 | ### Accounts with non-standard shells 96 | ``` 97 | grep -v "/sh$" /etc/passwd 98 | ``` 99 | ### Valid shells 100 | ``` 101 | cat /etc/shells 102 | ``` 103 | ### SSH ACLs configured 104 | ``` 105 | grep "Match" /etc/ssh/sshd_config 106 | ``` 107 | ### SSH user logins 108 | ``` 109 | egrep "AllowUsers|DenyUsers|AllowGroups|DenyGroups" /etc/ssh/sshd_config 110 | ``` 111 | ### SSH root logins 112 | ``` 113 | grep "PermitRootLogin" /etc/ssh/sshd_config 114 | ``` 115 | ### SSH TCP forwarding 116 | ``` 117 | grep "AllowTCPForwarding" /etc/ssh/sshd_config 118 | ``` 119 | ### SSH gateway ports 120 | ``` 121 | grep "GatewayPorts" /etc/ssh/sshd_config 122 | ``` 123 | ### SSH VPN 124 | ``` 125 | grep "PermitTunnel" /etc/ssh/sshd_config 126 | ``` 127 | ### SSH agent forwarding 128 | ``` 129 | grep "AllowAgentForwarding" /etc/ssh/sshd_config 130 | ``` 131 | ### SSH X11 forwarding 132 | ``` 133 | grep "X11Forwarding" /etc/ssh/sshd_config 134 | ``` 135 | ### SSH binds X11 to localhost 136 | ``` 137 | grep "X11UseLocalhost" /etc/ssh/sshd_config 138 | ``` 139 | ### SSH reads environment from user file 140 | ``` 141 | grep "PermitUserEnvironment" /etc/ssh/sshd_config 142 | ``` 143 | ### SSH accepts environment variables 144 | ``` 145 | grep "AcceptEnv" /etc/ssh/sshd_config 146 | ``` 147 | ### SSH looks up connections in DNS 148 | ``` 149 | grep "UseDNS" /etc/ssh/sshd_config 150 | ``` 151 | ### SSH uses privilege separation 152 | ``` 153 | grep "UsePrivilegeSeparation" /etc/ssh/sshd_config 154 | ``` 155 | ### .shosts used 156 | ``` 157 | find / -name .shosts -ls 158 | ``` 159 | ### shosts.equiv used 160 | ``` 161 | cat /etc/shosts.equiv 162 | ``` 163 | ### SSH allows .rhosts 164 | ``` 165 | grep "IgnoreRhosts" /etc/ssh/sshd_config 166 | ``` 167 | ### SSH public/private keys used 168 | ``` 169 | find / -name id_dsa -o -name id_dsa.pub -o -name id_rsa -o -name id_rsa.pub -o -name authorized_keys -ls 170 | ``` 171 | ### SSH sessions are throttled 172 | ``` 173 | egrep "MaxAuthTries|MaxSessions|MaxStartups" /etc/ssh/sshd_config 174 | ``` 175 | ### FTP users disallowed 176 | ``` 177 | cat /etc/ftpusers 178 | ``` 179 | ### NFS shares 180 | ``` 181 | cat /etc/exports 182 | ``` 183 | ### Secure consoles 184 | ``` 185 | cat /etc/security/user 186 | ``` 187 | ## Authentication 188 | Tags: authentication 189 | ### Banner 190 | ``` 191 | cat /etc/issue 192 | ``` 193 | ### MOTD 194 | ``` 195 | cat /etc/motd 196 | ``` 197 | ### Passwords 198 | ``` 199 | cat /etc/passwd 200 | cat /etc/security/passwd 201 | ``` 202 | ### SNMP community strings 203 | ``` 204 | grep "community" /etc/snmpd.conf 205 | ``` 206 | ### Login policy 207 | ``` 208 | cat /etc/security/login.cfg 209 | ``` 210 | ### Password aging 211 | ``` 212 | cat /etc/security/users 213 | ``` 214 | ### Password minimum strength 215 | ``` 216 | cat /etc/security/users 217 | ``` 218 | ### Unlocked accounts 219 | ``` 220 | cat /etc/security/passwd 221 | ``` 222 | ### Session timeout 223 | ``` 224 | echo $TMOUT 225 | ``` 226 | ### SSH shows banner 227 | ``` 228 | grep "Banner" /etc/ssh/sshd_config 229 | ``` 230 | ### SSH shows MOTD 231 | ``` 232 | grep "PrintMotd" /etc/ssh/sshd_config 233 | ``` 234 | ### SSH allows empty passwords 235 | ``` 236 | grep "PermitEmptyPasswords" /etc/ssh/sshd_config 237 | ``` 238 | ## Cryptography 239 | Tags: cryptography 240 | ### known_hosts encrypted 241 | ``` 242 | cat /.ssh/known_hosts 243 | ``` 244 | ### SSH protocol 245 | ``` 246 | grep "Protocol" /etc/ssh/sshd_config 247 | ``` 248 | ### SSH protocol 1 key regeneration 249 | ``` 250 | grep "KeyRegenerationInterval" /etc/ssh/sshd_config 251 | ``` 252 | ### SSH protocol 1 key size 253 | ``` 254 | grep "ServerKeyBits" /etc/ssh/sshd_config 255 | ``` 256 | ### SSH protocol 2 public key authentication 257 | ``` 258 | grep "PubkeyAuthentication" /etc/ssh/sshd_config 259 | ``` 260 | ### SSH allows .rhosts with protocol 1 RSA 261 | ``` 262 | grep "RhostsRSAAuthentication" /etc/ssh/sshd_config 263 | ``` 264 | ### SSH allows protocol 1 RSA 265 | ``` 266 | grep "RSAAuthentication" /etc/ssh/sshd_config 267 | ``` 268 | ### SSH password based authentication 269 | ``` 270 | grep "PasswordAuthentication" /etc/ssh/sshd_config 271 | ``` 272 | ### SSH ciphers 273 | ``` 274 | grep "Ciphers" /etc/ssh/sshd_config 275 | ``` 276 | ### SSH MACs 277 | ``` 278 | grep "MACs" /etc/ssh/sshd_config 279 | ``` 280 | ### Blacklisted keys 281 | ``` 282 | grep "PermitBlacklistedKeys" /etc/ssh/sshd_config 283 | ``` 284 | ### Crypto used for shadow 285 | ``` 286 | grep "pwd_algorithm" /etc/security/login.cfg 287 | ``` 288 | ## Software installed 289 | Tags: software-installed 290 | ### OS release 291 | ``` 292 | oslevel -sq 293 | oslevel -rq 294 | ``` 295 | ### Packages installed 296 | ``` 297 | lslpp -Lc 298 | rpm -q -a 299 | ``` 300 | ### Processes 301 | ``` 302 | ps -aef 303 | ``` 304 | ### Services 305 | ``` 306 | lssrc -a 307 | lssrc -a | grep -v "Sub" | while read subsystem _ 308 | do 309 | echo "Subsystem: $subsystem" 310 | lssrc -ls $subsystem 311 | done 312 | ``` 313 | ### Development tools 314 | ``` 315 | find / -type f \( -name perl -o -name gcc -o -name javac -o -name python -o -name ruby -o -name gdb \) 316 | ``` 317 | ### 3rd party software 318 | ``` 319 | find /usr/local -ls 320 | find /opt -ls 321 | ``` 322 | ## Logging 323 | Tags: logging 324 | ### Time synchronisation 325 | ``` 326 | ps -aef | grep "ntp" 327 | ``` 328 | ### Remote logging 329 | ``` 330 | grep "@" /etc/syslog.conf 331 | ``` 332 | ### Cron logging 333 | ``` 334 | grep "cron" /etc/syslog.conf 335 | ``` 336 | ## Resource limits 337 | Tags: resource-limits 338 | ### Configured limits 339 | ``` 340 | cat /etc/security/limits 341 | ``` 342 | ### Running limits 343 | ``` 344 | ulimit -a 345 | ``` 346 | ### Disk quotas 347 | ``` 348 | lsfs | grep "Quota" 349 | ``` 350 | ## File permissions 351 | Tags: file-permissions 352 | ### Init umask 353 | ``` 354 | grep "umask" /etc/rc.* 355 | ``` 356 | ### FTP umask 357 | ``` 358 | grep "ftpd" /etc/inetd.conf 359 | ``` 360 | ### Root umask 361 | ``` 362 | umask 363 | ``` 364 | ### User umask 365 | ``` 366 | grep "umask" /home/*/.[a-z]* 367 | grep "umask" /etc/security/.profile 368 | grep "umask" /etc/profile 369 | cat /etc/security/user 370 | ``` 371 | ### Service umasks 372 | ``` 373 | grep "umask" /etc/rc*.d/* 374 | ``` 375 | ### World readable files / directories 376 | ``` 377 | find / -perm -o+r -ls 378 | ``` 379 | ### World writable files / directories 380 | ``` 381 | find / -perm -o+w -ls 382 | ``` 383 | ### Group writable files / directories 384 | ``` 385 | find / -perm -o+w -ls 386 | ``` 387 | ### Unowned files / directories 388 | ``` 389 | find / -nouser -ls 390 | ``` 391 | ### Ungrouped files / directories 392 | ``` 393 | find / -nogroup -ls 394 | ``` 395 | ### Log files 396 | ``` 397 | find /var/log /var/adm -ls 398 | ``` 399 | ### SSH strict mode 400 | ``` 401 | grep "StrictModes" /etc/ssh/sshd_config 402 | ``` 403 | ### Root home 404 | ``` 405 | find /root -ls 406 | ``` 407 | ## Exploit mitigation 408 | Tags: exploit-mitigation 409 | ### Active mounts secure 410 | ``` 411 | mount | grep -v "nosetuid" 412 | mount | grep -v "noexec" 413 | lsfs 414 | ``` 415 | ### Configured mounts secure 416 | ``` 417 | cat /etc/filesystems 418 | ``` 419 | ### Separate partitions 420 | ``` 421 | mount | grep "/var" 422 | mount | grep "/var/log" 423 | mount | grep "/home" 424 | ``` 425 | ### Cron users 426 | ``` 427 | cat /var/adm/cron/cron.allow /var/adm/cron/cron.deny 428 | ``` 429 | ### At users 430 | ``` 431 | cat /var/adm/cron/at.allow /var/adm/cron/at.deny 432 | ``` 433 | ### Non executable stack 434 | ``` 435 | sedmgr 436 | ``` 437 | ## Privilege escalation 438 | Tags: privilege-escalation 439 | ### Init scripts run 440 | ``` 441 | cat /etc/inittab 442 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 443 | do 444 | echo "File: $file" 445 | ls -la $file 446 | done 447 | ls -la /etc/rc.* 448 | ``` 449 | ### At scripts run 450 | ``` 451 | for file in /var/spool/atjobs/* 452 | do 453 | echo "File: $file" 454 | ls -l $file 455 | cat $file 456 | done 457 | ``` 458 | ### Cron scripts run 459 | ``` 460 | for file in /var/spool/cron/* 461 | do 462 | echo "File: $file" 463 | ls -l $file 464 | cat $file 465 | done 466 | ``` 467 | ### Default path 468 | ``` 469 | echo $PATH 470 | ``` 471 | ### User paths 472 | ``` 473 | grep "PATH" /home/*/.[a-z]* 474 | ``` 475 | ### Init paths 476 | ``` 477 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 478 | do 479 | echo "File: $file" 480 | grep "PATH" $file 481 | done 482 | grep "PATH" /etc/rc.* 483 | ``` 484 | ### Default linker path 485 | ``` 486 | grep "LD_LIBRARY_PATH" /etc/profile 487 | echo $LD_LIBRARY_PATH 488 | ``` 489 | ### User linker paths 490 | ``` 491 | egrep "LIBPATH|LD_LIBRARY_PATH" /home/*/.[a-z]* 492 | ``` 493 | ### Init linker paths 494 | ``` 495 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 496 | do 497 | echo "File: $file" 498 | egrep "LIBPATH|LD_LIBRARY_PATH" $file 499 | done 500 | egrep "LIBPATH|LD_LIBRARY_PATH" /etc/rc.* 501 | ``` 502 | ### SetUID files 503 | ``` 504 | find / -perm -u+s -type f -ls 505 | ``` 506 | ### SetGID files 507 | ``` 508 | find / -perm -g+s -type f -ls 509 | ``` 510 | ### Sudo configuration 511 | ``` 512 | cat /etc/sudoers 513 | ``` 514 | ## Common services 515 | Tags: common-services 516 | ### SSH running config 517 | ``` 518 | sshd -T 519 | ``` 520 | ### Web server config 521 | ``` 522 | find / -name httpd.conf | while read file 523 | do 524 | echo "File: $file" 525 | ls -l $file 526 | cat $file 527 | done 528 | ``` 529 | ### Web server cgi-bin 530 | ``` 531 | find /usr/lib -name cgi-bin | while read file 532 | do 533 | echo "File: $file" 534 | ls -l $file 535 | done 536 | -------------------------------------------------------------------------------- /checks-database/linux.md: -------------------------------------------------------------------------------- 1 | # Linux 2 | PlatformTag: linux 3 | ## Informational 4 | Tags: informational 5 | ### Date 6 | ``` 7 | date 8 | ``` 9 | ### Hostname 10 | ``` 11 | hostname 12 | ``` 13 | ### Kernel version 14 | ``` 15 | uname -a 16 | ``` 17 | ### Network interfaces (ifconfig) 18 | ``` 19 | ifconfig -a 20 | ``` 21 | ### Network interfaces (ip) 22 | ``` 23 | ip -a 24 | ``` 25 | ### Running as 26 | ``` 27 | id 28 | ``` 29 | ## Environment 30 | Tags: environment 31 | ### PCI cards accessible 32 | ``` 33 | lspci 34 | ``` 35 | ### USB peripherals accessible 36 | ``` 37 | lsusb 38 | ``` 39 | ### Boot flags 40 | ``` 41 | cat /proc/cmdline 42 | ``` 43 | ### Kernel logs 44 | ``` 45 | dmesg 46 | ``` 47 | ### Kernel config 48 | ``` 49 | cat /boot/config-`uname -r` 50 | ``` 51 | ### Loaded kernel modules 52 | ``` 53 | lsmod 54 | ``` 55 | ### Kernel modules supported 56 | ``` 57 | grep "CONFIG_MODULES" /boot/config-`uname -r` 58 | ``` 59 | ### Kernel modules 60 | ``` 61 | sysctl kernel.modules_disabled 62 | ``` 63 | ### Grub password set 64 | ``` 65 | grep "password" /boot/grub/menu.lst 66 | ``` 67 | ### Ctrl-alt-delete 68 | ``` 69 | grep "ctrlaltdel" /etc/inittab 70 | ``` 71 | ### Kernel debugging 72 | ``` 73 | grep "sysrq" /etc/sysctl.conf 74 | ``` 75 | ### Kernel hardening 76 | ``` 77 | cat /etc/sysctl.conf 78 | ``` 79 | ### Active kernel hardening 80 | ``` 81 | sysctl -a 82 | ``` 83 | ### Host is KVM 84 | ``` 85 | cat /proc/cpuinfo | grep -i "qemu" 86 | ``` 87 | ### Host is VMware 88 | ``` 89 | dmidecode | grep -i "vmware" 90 | ``` 91 | ### Host is VirtualBox 92 | ``` 93 | dmidecode | grep -i "virtualbox" 94 | ``` 95 | ### Host is Xen 96 | ``` 97 | dmidecode | grep -i "xen" 98 | ``` 99 | ### Host is container 100 | ``` 101 | cat /proc/1/cgroup 102 | ``` 103 | ### Containers 104 | ``` 105 | docker ps -a 106 | ``` 107 | ### K8s cluster 108 | ``` 109 | kubectl config view 110 | ``` 111 | ### Environment variables set 112 | ``` 113 | env 114 | ``` 115 | ### Currently logged in 116 | ``` 117 | who 118 | ``` 119 | ### Logins 120 | ``` 121 | last 122 | ``` 123 | ## Networking 124 | Tags: networking 125 | ### ARP 126 | ``` 127 | arp -an 128 | ``` 129 | ### ARP (using ip) 130 | ``` 131 | ip -4 neigh show 132 | ``` 133 | ### IPv6 neighbor table 134 | ``` 135 | ip -6 neigh show 136 | ``` 137 | ### Routing (netstat) 138 | ``` 139 | netstat -rn 140 | ``` 141 | ### Routing (ip) 142 | ``` 143 | ip route show 144 | ``` 145 | ### Name services 146 | ``` 147 | cat /etc/nsswitch.conf 148 | ``` 149 | ### Hosts 150 | ``` 151 | cat /etc/hosts 152 | ``` 153 | ### DNS 154 | ``` 155 | cat /etc/resolv.conf 156 | ``` 157 | ### Internet (IPv4) 158 | ``` 159 | ping -4 -c 5 www.google.co.uk 160 | ping -c 5 8.8.8.8 161 | ``` 162 | ### Internet (IPv6) 163 | ``` 164 | ping -6 -c 5 www.google.co.uk 165 | ping -c 5 2001:4860:4860::8888 166 | ``` 167 | ### Web accessible (IPv4) 168 | ``` 169 | wget -O - https://216.58.213.164 170 | wget -O -4 - https://www.google.com 171 | curl https://216.58.213.164 172 | curl -4 https://www.google.com 173 | ``` 174 | ### Web accessible (IPv6) 175 | ``` 176 | wget -O - https://[2600::] 177 | wget -6 -O - https://www.google.com 178 | curl https://[2600::] 179 | curl -6 https://www.google.com 180 | ``` 181 | ### Internet by proxy 182 | ``` 183 | echo $http_proxy 184 | echo $https_proxy 185 | echo $ftp_proxy 186 | ``` 187 | ### Listening services (netstat) 188 | ``` 189 | netstat -anp | grep -v "unix" | grep "LISTEN" 190 | ``` 191 | ### Listening services (socket stat) 192 | ``` 193 | ss -tulpan | grep LISTEN 194 | ``` 195 | 196 | ### RPC services 197 | ``` 198 | rpcinfo -p 199 | ``` 200 | ### IPv6 (ifconfig) 201 | ``` 202 | ifconfig lo | grep "::1" 203 | ``` 204 | ### IPv6 (ip) 205 | ``` 206 | ip addr show dev lo | grep ::1 207 | ``` 208 | ### Network traffic 209 | ``` 210 | # Possible alternative to which for non Linux systems: 211 | # if ! [ -x "$(command -v tcpdump)" ]; then 212 | if ! [ "$(which tcpdump)" ]; then 213 | echo 'Error: tcpdump is not installed.' >&2 214 | else 215 | # Capture traffic on all interfaces, for 60 seconds: 216 | # -G 60 (rotate dump files every x seconds) 217 | # -W 1 (limit number of dump files) 218 | # Filter out traffic on port 22 to avoid feedback loop: 219 | # port not 22 220 | tcpdump -G 60 -W 1 -i any -s 65535 port not 22 -w packet_capture-`hostname`.pcap 221 | fi 222 | tar cvf packet_capture-`hostname`.tar packet_capture-`hostname`.pcap 223 | gzip packet_capture-`hostname`.tar 224 | rm packet_capture-`hostname`.pcap 225 | ``` 226 | ## Network stack tuning 227 | Tags: network-stack-tuning 228 | ### Syncookies 229 | ``` 230 | cat /proc/sys/net/ipv4/tcp_syncookies 231 | grep "syncookies" /etc/sysctl.conf 232 | ``` 233 | ### IP forwarding 234 | ``` 235 | cat /proc/sys/net/ipv4/ip_forward 236 | grep "ip_forward" /etc/sysctl.conf 237 | ``` 238 | ### Network shares mounted 239 | ``` 240 | mount | grep "cifs" 241 | mount | grep "nfs" 242 | ``` 243 | ## Access control 244 | Tags: access-control 245 | ### Firewall configured 246 | ``` 247 | iptables -L 248 | ip6tables -L 249 | ``` 250 | ### TCP wrappers used 251 | ``` 252 | cat /etc/hosts.allow 253 | cat /etc/hosts.deny 254 | ``` 255 | ### .rhosts used 256 | ``` 257 | find / -name .rhosts -ls 258 | ``` 259 | ### hosts.equiv used 260 | ``` 261 | cat /etc/hosts.equiv 262 | ``` 263 | ### .netrc used 264 | ``` 265 | find / -name .netrc -ls 266 | ``` 267 | ### Remote X 268 | ``` 269 | grep "nolistentcp" /etc/X11/xdm/Xservers /etc/kde/kdm/Xservers /etc/X11/gdm/gdm.conf /etc/X11/xinit/xserverrc 270 | ``` 271 | ### X root logins 272 | ``` 273 | grep "AllowRootLogin" /etc/X11/xdm/kdmrc 274 | ``` 275 | ### Account statuses 276 | ``` 277 | passwd -S -a 278 | ``` 279 | ### Accounts with non-standard shells 280 | ``` 281 | grep -v "/bash$" /etc/passwd 282 | ``` 283 | ### Valid shells 284 | ``` 285 | cat /etc/shells 286 | ``` 287 | ### SSH ACLs configured 288 | ``` 289 | grep "Match" /etc/ssh/sshd_config 290 | ``` 291 | ### SSH user logins 292 | ``` 293 | egrep "AllowUsers|DenyUsers|AllowGroups|DenyGroups" /etc/ssh/sshd_config 294 | ``` 295 | ### SSH root logins 296 | ``` 297 | grep "PermitRootLogin" /etc/ssh/sshd_config 298 | ``` 299 | ### SSH TCP forwarding 300 | ``` 301 | grep "AllowTCPForwarding" /etc/ssh/sshd_config 302 | ``` 303 | ### SSH gateway ports 304 | ``` 305 | grep "GatewayPorts" /etc/ssh/sshd_config 306 | ``` 307 | ### SSH VPN 308 | ``` 309 | grep "PermitTunnel" /etc/ssh/sshd_config 310 | ``` 311 | ### SSH agent forwarding 312 | ``` 313 | grep "AllowAgentForwarding" /etc/ssh/sshd_config 314 | ``` 315 | ### SSH X11 forwarding 316 | ``` 317 | grep "X11Forwarding" /etc/ssh/sshd_config 318 | ``` 319 | ### SSH binds X11 to localhost 320 | ``` 321 | grep "X11UseLocalhost" /etc/ssh/sshd_config 322 | ``` 323 | ### SSH reads environment from user file 324 | ``` 325 | grep "PermitUserEnvironment" /etc/ssh/sshd_config 326 | ``` 327 | ### SSH accepts environment variables 328 | ``` 329 | grep "AcceptEnv" /etc/ssh/sshd_config 330 | ``` 331 | ### SSH looks up connections in DNS 332 | ``` 333 | grep "UseDNS" /etc/ssh/sshd_config 334 | ``` 335 | ### SSH uses privilege separation 336 | ``` 337 | grep "UsePrivilegeSeparation" /etc/ssh/sshd_config 338 | ``` 339 | ### .shosts used 340 | ``` 341 | find / -name .shosts -ls 342 | ``` 343 | ### shosts.equiv used 344 | ``` 345 | cat /etc/shosts.equiv 346 | ``` 347 | ### SSH allows .rhosts 348 | ``` 349 | grep "IgnoreRhosts" /etc/ssh/sshd_config 350 | ``` 351 | ### SSH public/private keys used 352 | ``` 353 | find / \( -name id_dsa -o -name id_dsa.pub -o -name id_rsa -o -name id_rsa.pub -o -name authorized_keys \) | while read file 354 | do 355 | ls -l $file 356 | cat $file 357 | done 358 | ``` 359 | ### SSH sessions are throttled 360 | ``` 361 | egrep "MaxAuthTries|MaxSessions|MaxStartups" /etc/ssh/sshd_config 362 | ``` 363 | ### FTP users disallowed 364 | ``` 365 | cat /etc/ftpusers 366 | ``` 367 | ### NFS shares 368 | ``` 369 | cat /etc/exports 370 | ``` 371 | ### SMB shares 372 | ``` 373 | cat /etc/samba/smb.conf 374 | ``` 375 | ### Secure consoles 376 | ``` 377 | cat /etc/securetty 378 | ``` 379 | ## Authentication 380 | Tags: authentication 381 | ### Banner 382 | ``` 383 | cat /etc/issue 384 | ``` 385 | ### MOTD 386 | ``` 387 | cat /etc/motd 388 | ``` 389 | ### Passwords 390 | ``` 391 | cat /etc/passwd 392 | cat /etc/shadow 393 | ``` 394 | ### Active Directory enabled 395 | ``` 396 | ps -aef | grep "vasd|sssd|pbis|slapd|adclient" 397 | ``` 398 | ### Non-local users 399 | ``` 400 | getent passwd 401 | getent group 402 | ``` 403 | ### Using NIS 404 | ``` 405 | ypcat passwd 406 | ``` 407 | ### Using Kerberos 408 | ``` 409 | for file in /tmp/krb5* 410 | do 411 | ls -l $file 412 | done 413 | ``` 414 | ### Using LDAP 415 | ``` 416 | cat /etc/ldap/ldap.conf 417 | ``` 418 | ### SNMP community strings 419 | ``` 420 | grep community /etc/snmp/snmpd.conf 421 | ``` 422 | ### System Auth PAM 423 | ``` 424 | grep "limits" /etc/pam.d/* 425 | grep "crack" /etc/pam.d/* 426 | grep "nullok" /etc/pam.d/* 427 | grep "md5" /etc/pam.d/* 428 | grep "shadow" /etc/pam.d/* 429 | grep "cap" /etc/pam.d/* 430 | ``` 431 | ### Login PAM 432 | ``` 433 | grep "nologin" /etc/pam.d/* 434 | grep "securetty" /etc/pam.d/* 435 | grep "limits" /etc/pam.d/* 436 | grep "cap" /etc/pam.d/* 437 | ``` 438 | ### Su PAM 439 | ``` 440 | grep "nologin" /etc/pam.d/* 441 | grep "securetty" /etc/pam.d/* 442 | grep "limits" /etc/pam.d/* 443 | grep "wheel" /etc/pam.d/* 444 | grep "cap" /etc/pam.d/* 445 | ``` 446 | ### Sudo PAM 447 | ``` 448 | grep "nologin" /etc/pam.d/* 449 | grep "securetty" /etc/pam.d/* 450 | grep "limits" /etc/pam.d/* 451 | grep "wheel" /etc/pam.d/* 452 | grep "cap" /etc/pam.d/* 453 | ``` 454 | ### Password aging 455 | ``` 456 | grep "MAX_DAYS" /etc/login.defs 457 | grep "MIN_DAYS" /etc/login.defs 458 | ``` 459 | ### Password minimum strength 460 | ``` 461 | grep "MIN_LEN" /etc/login.defs 462 | ``` 463 | ### Unlocked accounts 464 | ``` 465 | grep -v "!!" /etc/shadow 466 | ``` 467 | ### Session timeout 468 | ``` 469 | echo $TMOUT 470 | ``` 471 | ### SSH shows banner 472 | ``` 473 | grep "Banner" /etc/ssh/sshd_config 474 | ``` 475 | ### SSH shows MOTD 476 | ``` 477 | grep "PrintMotd" /etc/ssh/sshd_config 478 | ``` 479 | ### SSH uses PAM 480 | ``` 481 | grep "UsePAM" /etc/ssh/sshd_config 482 | ``` 483 | ### SSH allows empty passwords 484 | ``` 485 | grep "PermitEmptyPasswords" /etc/ssh/sshd_config 486 | ``` 487 | ## Cryptography 488 | Tags: cryptography 489 | ### known_hosts encrypted 490 | ``` 491 | find / -name known_hosts | while read file 492 | do 493 | ls -l $file 494 | cat $file 495 | done 496 | ``` 497 | ### SSH protocol 498 | ``` 499 | grep "Protocol" /etc/ssh/sshd_config 500 | ``` 501 | ### SSH protocol 1 key regeneration 502 | ``` 503 | grep "KeyRegenerationInterval" /etc/ssh/sshd_config 504 | ``` 505 | ### SSH protocol 1 key size 506 | ``` 507 | grep "ServerKeyBits" /etc/ssh/sshd_config 508 | ``` 509 | ### SSH protocol 2 public key authentication 510 | ``` 511 | grep "PubkeyAuthentication" /etc/ssh/sshd_config 512 | ``` 513 | ### SSH allows .rhosts with protocol 1 RSA 514 | ``` 515 | grep "RhostsRSAAuthentication" /etc/ssh/sshd_config 516 | ``` 517 | ### SSH allows protocol 1 RSA 518 | ``` 519 | grep "RSAAuthentication" /etc/ssh/sshd_config 520 | ``` 521 | ### SSH password based authentication 522 | ``` 523 | grep "PasswordAuthentication" /etc/ssh/sshd_config 524 | ``` 525 | ### SSH ciphers 526 | ``` 527 | grep "Ciphers" /etc/ssh/sshd_config 528 | ``` 529 | ### SSH MACs 530 | ``` 531 | grep "MACs" /etc/ssh/sshd_config 532 | ``` 533 | ### Blacklisted keys 534 | ``` 535 | grep "PermitBlacklistedKeys" /etc/ssh/sshd_config 536 | ``` 537 | ### Grub password obfuscated 538 | ``` 539 | grep "password" /boot/grub/menu.lst | grep "md5" 540 | ``` 541 | ### Crypto used for shadow 542 | ``` 543 | egrep "MD5_CRYPT_ENAB|ENCRYPT_METHOD" /etc/login.defs 544 | ``` 545 | ### Trusted CAs 546 | ``` 547 | md5sum /etc/ssl/certs/* 548 | ``` 549 | ### Trusted keyrings 550 | ``` 551 | md5sum /etc/apt/trusted.gpg.d/* 552 | md5sum /etc/pki/rpm-gpg/* 553 | ``` 554 | ## Software installed 555 | Tags: software-installed 556 | ### OS release 557 | ``` 558 | cat /etc/*-release /etc/debian_version 559 | ``` 560 | ### Packages installed 561 | ``` 562 | rpm -q -a 563 | dpkg --list --no-pager 564 | ``` 565 | ### Packages for NOPC 566 | ``` 567 | rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}|%{EPOCH}\n' 568 | dpkg -l --no-pager 569 | ``` 570 | ### Package management 571 | ``` 572 | cat /etc/apt/apt.conf 573 | for file in /etc/apt/apt.conf /etc/apt/apt.conf.d/* /etc/apt/sources.list /etc/apt/sources.list.d/* /etc/yum.conf /etc/yum.repos.d/*.repo /etc/dnf/dnf.conf 574 | do 575 | ls -l $file 576 | cat $file 577 | done 578 | ``` 579 | ### Processes 580 | ``` 581 | ps -aef 582 | ``` 583 | ### Services 584 | ``` 585 | chkconfig --list 586 | ``` 587 | ### Systemd services 588 | ``` 589 | systemctl --no-pager 590 | ``` 591 | ### Systemd configs 592 | ``` 593 | find /usr/lib/systemd/* /etc/systemd/* -type f | while read file 594 | do 595 | ls -l $file 596 | cat $file 597 | done 598 | ``` 599 | ### Development tools 600 | ``` 601 | find / -type f \( -name perl -o -name gcc -o -name javac -o -name python -o -name ruby -o -name gdb \) -ls 602 | ``` 603 | ### 3rd party software 604 | ``` 605 | find /usr/local -ls 606 | find /opt -ls 607 | ``` 608 | ## Logging 609 | Tags: logging 610 | ### Time synchronisation 611 | ``` 612 | ps -aef | grep "ntp" 613 | ``` 614 | ### Syslog process 615 | ``` 616 | ps -aef | grep syslog 617 | ``` 618 | ### Remote logging 619 | ``` 620 | grep "@" /etc/syslog.conf 621 | ``` 622 | ### Syslog with rsyslog 623 | ``` 624 | for file in /etc/rsyslog.conf /etc/rsyslog.d/* 625 | do 626 | ls -l $file 627 | cat $file 628 | done 629 | ``` 630 | ### Syslog with syslog-ng 631 | ``` 632 | cat /etc/syslog-ng/syslog-ng.conf 633 | ``` 634 | ### Cron logging 635 | ``` 636 | grep "cron" /etc/syslog.conf 637 | ``` 638 | ### User histories 639 | ``` 640 | find /home \( -name .sh_history -o -name .bash_history \) | while read file 641 | do 642 | ls -l $file 643 | cat $file 644 | done 645 | ``` 646 | ### Auditing 647 | ``` 648 | ps -aef | grep auditd 649 | auditctl -s 650 | ``` 651 | ### Auditd policy 652 | ``` 653 | for file in /etc/audit/audit.rules /etc/audit/audit.rules.d/* 654 | do 655 | ls -l $file 656 | cat $file 657 | done 658 | ``` 659 | ## Resource limits 660 | Tags: resource-limits 661 | ### Configured limits 662 | ``` 663 | cat /etc/security/limits.conf 664 | ``` 665 | ### Running limits 666 | ``` 667 | ulimit -a 668 | ``` 669 | ### Tmp size 670 | ``` 671 | mount | grep "/tmp" | grep "size" 672 | ``` 673 | ### Disk quotas 674 | ``` 675 | mount | grep "quota" 676 | ``` 677 | ## File permissions 678 | Tags: file-permissions 679 | ### Init umask 680 | ``` 681 | grep "umask" /etc/rc.d/init.d/functions 682 | ``` 683 | ### Syslog umask 684 | ``` 685 | grep "umask" /etc/rc.d/init.d/syslog /etc/sysconfig/syslog 686 | ``` 687 | ### Root umask 688 | ``` 689 | umask 690 | ``` 691 | ### User umask 692 | ``` 693 | grep "UMASK" /etc/login.defs 694 | grep "umask" /home/*/.[a-z]* 695 | ``` 696 | ### Service umasks 697 | ``` 698 | grep "umask" /etc/rc.d/rc*.d/* 699 | ``` 700 | ### World readable files / directories 701 | ``` 702 | find / -perm -o+r -ls 703 | ``` 704 | ### World writable files / directories 705 | ``` 706 | find / -perm -o+w -ls 707 | ``` 708 | ### Group writable files / directories 709 | ``` 710 | find / -perm -o+w -ls 711 | ``` 712 | ### Unowned files / directories 713 | ``` 714 | find / -nouser -ls 715 | ``` 716 | ### Ungrouped files / directories 717 | ``` 718 | find / -nogroup -ls 719 | ``` 720 | ### Log files 721 | ``` 722 | ls -la /var/log 723 | ``` 724 | ### SSH strict mode 725 | ``` 726 | grep "StrictModes" /etc/ssh/sshd_config 727 | ``` 728 | ### Root home 729 | ``` 730 | find /root -ls 731 | ``` 732 | ### User homes 733 | ``` 734 | ls -la /home/* 735 | ``` 736 | ## Exploit mitigation 737 | Tags: exploit-mitigation 738 | ### Active mounts secure 739 | ``` 740 | mount | grep -v "nosetuid" 741 | mount | grep -v "noexec" 742 | ``` 743 | ### Configured mounts secure 744 | ``` 745 | grep -v "nosetuid" /etc/fstab 746 | grep -v "noexec" /etc/fstab 747 | ``` 748 | ### Separate partitions 749 | ``` 750 | mount | grep "/var" 751 | mount | grep "/var/log" 752 | mount | grep "/home" 753 | ``` 754 | ### SELinux supported 755 | ``` 756 | grep "SELINUX=" /etc/selinux/config 757 | ``` 758 | ### SELinux policy 759 | ``` 760 | grep "SELINUXTYPE=" /etc/selinux/config 761 | ``` 762 | ### SELinux running 763 | ``` 764 | selinux -v 765 | ``` 766 | ### SELinux processes 767 | ``` 768 | ps -aefZ 769 | ``` 770 | ### AppArmour supported 771 | ``` 772 | cat /sys/module/apparmor/parameters/enabled 773 | ``` 774 | ### AppArmour policy 775 | ``` 776 | aa-status 777 | ``` 778 | ### AppArmour processes 779 | ``` 780 | aa-unconfined 781 | ps -aefZ 782 | ``` 783 | ### Cron users 784 | ``` 785 | cat /etc/cron.allow /etc/cron.deny 786 | ``` 787 | ### At users 788 | ``` 789 | cat /etc/at.allow /etc/at.deny 790 | ``` 791 | ### Stack randomisation 792 | ``` 793 | sysctl kernel.randomize_va_space 794 | ``` 795 | ### Non executable stack 796 | ``` 797 | grep "stack" /proc/[0-9]*/maps 798 | ``` 799 | ### Stack smashing protection 800 | ``` 801 | for x in /proc/[0-9]* 802 | do 803 | ls -l $x/exe | sed "s/.* -> //g" 804 | objdump -D $x/exe | grep stack_chk | sort | uniq 805 | done 806 | find / \( -perm -u+s -o -perm -g+s \) | while read file 807 | do 808 | ls -l $file 809 | objdump -D $file | grep "stack_chk" | sort | uniq 810 | done 811 | ``` 812 | ### SetUID debug 813 | ``` 814 | ls -l /etc/suid-debug 815 | ``` 816 | ### PTrace scope 817 | ``` 818 | sysctl -a | grep "ptrace_scope" 819 | ``` 820 | ## Privilege escalation 821 | Tags: privilege-escalation 822 | ### User capabilities 823 | ``` 824 | ls -l /etc/security/capability.conf 825 | cat /etc/security/capability.conf 826 | ``` 827 | ### Init scripts run 828 | ``` 829 | for file in /etc/rc.d/*.d/* 830 | do 831 | ls -l $file 832 | cat $file 833 | done 834 | ``` 835 | ### At scripts run 836 | ``` 837 | for file in /var/spool/atjobs/* 838 | do 839 | ls -l $file 840 | cat $file 841 | done 842 | ``` 843 | ### Cron scripts run 844 | ``` 845 | for file in /etc/crontab /var/spool/crontabs/* /etc/cron.d/* /etc/cron.daily/* /etc/cron.weekly/* /etc/cron.monthly/* /etc/cron.hourly/* 846 | do 847 | ls -l $file 848 | cat $file 849 | done 850 | ``` 851 | ### Default path 852 | ``` 853 | echo $PATH 854 | ``` 855 | ### User paths 856 | ``` 857 | for file in /etc/profile /etc/bash.bashrc /home/*/.[a-z]* 858 | do 859 | ls -l $file 860 | grep "PATH" $file 861 | done 862 | ``` 863 | ### Init paths 864 | ``` 865 | for file in /etc/rc.d/init.d/* 866 | do 867 | ls -l $file 868 | grep "PATH" $file 869 | done 870 | ``` 871 | ### Default linker path 872 | ``` 873 | for file in /etc/ld.so.conf /etc/ld.so.conf.d/* 874 | do 875 | ls -l $file 876 | cat $file 877 | done 878 | ``` 879 | ### User linker paths 880 | ``` 881 | for file in /etc/profile /etc/bash.bashrc /home/*/.[a-z]* 882 | do 883 | ls -l $file 884 | grep "LD_LIBRARY_PATH" $file 885 | done 886 | ``` 887 | ### Init linker paths 888 | ``` 889 | for file in /etc/rc.d/init.d/* 890 | do 891 | ls -l $file 892 | grep "LD_LIBRARY_PATH" $file 893 | done 894 | ``` 895 | ### SetUID files 896 | ``` 897 | find / -perm -u+s -type f -ls 898 | ``` 899 | ### SetGID files 900 | ``` 901 | find / -perm -g+s -type f -ls 902 | ``` 903 | ### Sudo configuration 904 | ``` 905 | for file in /etc/sudoers /etc/sudoers.d/* 906 | do 907 | ls -l $file 908 | cat $file 909 | done 910 | ``` 911 | ### Insecure RPATHs 912 | ``` 913 | find / \( -perm -o+s -o -g+s \) | while read file 914 | do 915 | ls -l $file 916 | objdump -x $file | egrep "RPATH|RUNPATH" 917 | done 918 | ``` 919 | ### Processes with open files 920 | ``` 921 | lsof 922 | ``` 923 | ### Proc tree 924 | ``` 925 | find /proc -type f | while read file 926 | do 927 | ls -l $file 928 | strings $file 929 | done 930 | ``` 931 | ### Sys tree 932 | ``` 933 | find /sys -type f | while read file 934 | do 935 | ls -l $file 936 | strings $file 937 | done 938 | ``` 939 | ### POSIX shared memory 940 | ``` 941 | ls -la /dev/shm 942 | ``` 943 | ### System V shared memory 944 | ``` 945 | ipcs -a 946 | ``` 947 | ### UNIX sockets 948 | ``` 949 | find / -type s -ls 950 | ``` 951 | ## Common services 952 | Tags: common-services 953 | ### SSH config 954 | ``` 955 | cat /etc/ssh/sshd_config 956 | ``` 957 | ### SSH client config 958 | ``` 959 | cat /etc/ssh/ssh_config 960 | ``` 961 | ### SSH running config 962 | ``` 963 | sshd -T 964 | ``` 965 | ### Web server config 966 | ``` 967 | find / -name httpd.conf | while read file 968 | do 969 | ls -l $file 970 | cat $file 971 | done 972 | ``` 973 | ### Web server logs 974 | ``` 975 | find / -name access.log | while read file 976 | do 977 | ls -l $file 978 | grep -i "curl|wget|python|perl" $file 979 | done 980 | ``` 981 | ### Web server cgi-bin 982 | ``` 983 | find / -name cgi-bin | while read file 984 | do 985 | ls -l $file 986 | done 987 | ``` 988 | ## Important file locations 989 | Tags: important-file-locations 990 | ### Configs 991 | ``` 992 | tar cvf etc-`hostname`.tar /etc 993 | gzip etc-`hostname`.tar 994 | ``` 995 | ### Logs 996 | ``` 997 | tar cvf logs-`hostname`.tar /var/log 998 | gzip logs-`hostname`.tar 999 | ``` 1000 | ### SetUID and setGIDs files 1001 | ``` 1002 | tar cvf suids-`hostname`.tar `find / \( -perm -o+s -o -perm -g+s \)` 1003 | gzip suids-`hostname`.tar 1004 | ``` 1005 | ### Temporary locations 1006 | ``` 1007 | tar cvf tmp-`hostname`.tar /tmp /var/tmp /dev/shm /dev/mqueue /run/screen /run/lock /var/crash 1008 | gzip tmp-`hostname`.tar 1009 | ``` 1010 | ### Core files 1011 | ``` 1012 | tar cvf core-`hostname`.tar `find / -type f \( -name core -o -name core.[0-9]* \)` 1013 | gzip core-`hostname`.tar 1014 | ``` 1015 | -------------------------------------------------------------------------------- /checks-database/solaris.md: -------------------------------------------------------------------------------- 1 | # Solaris 2 | PlatformTag: solaris 3 | ## Informational 4 | Tags: informational 5 | ### Hostname 6 | ``` 7 | cat /etc/nodename 8 | ``` 9 | ### Kernel version 10 | ``` 11 | uname -a 12 | ``` 13 | ### Network interfaces 14 | ``` 15 | ifconfig -a 16 | ``` 17 | ## Environment 18 | Tags: environment 19 | ### PCI cards accessible 20 | ``` 21 | prtconf -v 22 | ``` 23 | ### USB peripherals accessible 24 | ``` 25 | prtconf -v 26 | ``` 27 | ### Loaded kernel modules 28 | ``` 29 | modinfo 30 | ``` 31 | ### OBP password set 32 | ``` 33 | eeprom | grep "security-mode" 34 | ``` 35 | ### OBP banner set 36 | ``` 37 | eeprom | grep "oem-banner" 38 | ``` 39 | ### Grub password set 40 | ``` 41 | /sbin/bootadm list-menu 42 | grep password "/path/to/menu.lst" 43 | ``` 44 | ### Stop-A 45 | ``` 46 | grep "abort_enable" /etc/system 47 | ``` 48 | ### Zones 49 | ``` 50 | zoneadm list 51 | ``` 52 | ## Networking 53 | Tags: networking 54 | ### ARP 55 | ``` 56 | arp -a 57 | cat /etc/ethers 58 | ``` 59 | ### Routing 60 | ``` 61 | netstat -rn 62 | cat /etc/defaultrouter 63 | ``` 64 | ### Name services 65 | ``` 66 | cat /etc/nsswitch.conf 67 | ``` 68 | ### Hosts 69 | ``` 70 | cat /etc/hosts 71 | ``` 72 | ### DNS 73 | ``` 74 | cat /etc/resolv.conf 75 | ``` 76 | ### Internet 77 | ``` 78 | ping -c 5 www.google.co.uk 79 | ping -c 5 8.8.8.8 80 | ``` 81 | ### Listening services 82 | ``` 83 | netstat -an | egrep "LISTEN|TCP|UDP" 84 | netstat -aun | egrep "LISTEN|TCP|UDP" 85 | ``` 86 | ### IPv6 87 | ``` 88 | ifconfig lo | grep "::1" 89 | ls /etc/hostname6.* 90 | ``` 91 | ## Network stack tuning 92 | Tags: network-stack-tuning 93 | ### IP forwarding 94 | ``` 95 | cat /etc/notrouter 96 | ndd /dev/ip ip_forwarding 97 | ndd /dev/ip ip6_forwarding 98 | ``` 99 | ### Source routing 100 | ``` 101 | ndd /dev/ip ip_forward_src_routed 102 | ndd /dev/ip ip6_forward_src_routed 103 | ``` 104 | ### Directed broadcasts 105 | ``` 106 | ndd /dev/ip ip_forward_directed_broadcasts 107 | ndd /dev/ip ip6_forward_directed_broadcasts 108 | ``` 109 | ### Echo broadcasts 110 | ``` 111 | ndd /dev/ip ip_respond_to_echo_broadcasts 112 | ndd /dev/ip ip_respond_to_echo_multicast 113 | ndd /dev/ip ip6_respond_to_echo_multicast 114 | ``` 115 | ### Timestamp broadcasts 116 | ``` 117 | ndd /dev/ip ip_respond_to_timestamp 118 | ndd /dev/ip ip_respond_to_timestamp_broadcast 119 | ``` 120 | ### Redirects 121 | ``` 122 | ndd /dev/ip ip_ignore_redirect 123 | ndd /dev/ip ip6_ignore_redirect 124 | ``` 125 | ### Netmask broadcasts 126 | ``` 127 | ndd /dev/ip ip_respond_to_address_mask_broadcast 128 | ``` 129 | ### TCP limits 130 | ``` 131 | ndd /dev/tcp tcp_conn_req_max_q 132 | ndd /dev/tcp tcp_conn_req_max_q0 133 | ``` 134 | ### Strict multihoming 135 | ``` 136 | ndd /dev/ip ip_strict_dst_multihoming 137 | ndd /dev/ip ip6_strict_dst_multihoming 138 | ``` 139 | ### Strong ISS 140 | ``` 141 | grep "TCP_STRONG_ISS" /etc/default/inetinit 142 | ndd /dev/tcp tcp_strong_iss 143 | ``` 144 | ### Generic tuning - we should break this down and cross reference OS 145 | ``` 146 | for device in arp ip ip6 rawip rawip6 sockets tcp udp 147 | do 148 | echo "Device: $device" 149 | ndd /dev/$device '?' | grep -v '?' | while read parameter _ 150 | do 151 | echo "Parameter: $parameter" 152 | ndd /dev/$device $parameter 153 | done 154 | done 155 | ``` 156 | ## Access control 157 | Tags: access-control 158 | ### Firewall configured 159 | ``` 160 | cat /etc/ipf/ipf.conf 161 | ``` 162 | ### TCP wrappers used 163 | ``` 164 | cat /etc/hosts.allow 165 | cat /etc/hosts.deny 166 | ``` 167 | ### .rhosts used 168 | ``` 169 | find / -name .rhosts -ls 170 | ``` 171 | ### hosts.equiv used 172 | ``` 173 | cat /etc/hosts.equiv 174 | ``` 175 | ### .netrc used 176 | ``` 177 | find / -name .netrc -ls 178 | ``` 179 | ### Remote X 180 | ``` 181 | netstat -an | grep "LISTEN" | egrep "6000|177" 182 | ``` 183 | ### Accounts with non-standard shells 184 | ``` 185 | grep -v "/bash$" /etc/passwd 186 | ``` 187 | ### Valid shells 188 | ``` 189 | cat /etc/shells 190 | ``` 191 | ### SSH ACLs configured 192 | ``` 193 | grep "Match" /etc/ssh/sshd_config 194 | ``` 195 | ### SSH user logins 196 | ``` 197 | egrep "AllowUsers|DenyUsers|AllowGroups|DenyGroups" /etc/ssh/sshd_config 198 | ``` 199 | ### SSH root logins 200 | ``` 201 | grep "PermitRootLogin" /etc/ssh/sshd_config 202 | ``` 203 | ### SSH TCP forwarding 204 | ``` 205 | grep "AllowTcpForwarding" /etc/ssh/sshd_config 206 | ``` 207 | ### SSH gateway ports 208 | ``` 209 | grep "GatewayPorts" /etc/ssh/sshd_config 210 | ``` 211 | ### SSH VPN 212 | ``` 213 | grep "PermitTunnel" /etc/ssh/sshd_config 214 | ``` 215 | ### SSH agent forwarding 216 | ``` 217 | grep "AllowAgentForwarding" /etc/ssh/sshd_config 218 | ``` 219 | ### SSH X11 forwarding 220 | ``` 221 | grep "X11Forwarding" /etc/ssh/sshd_config 222 | ``` 223 | ### SSH binds X11 to localhost 224 | ``` 225 | grep "X11UseLocalhost" /etc/ssh/sshd_config 226 | ``` 227 | ### SSH reads environment from user file 228 | ``` 229 | grep "PermitUserEnvironment" /etc/ssh/sshd_config 230 | ``` 231 | ### SSH accepts environment variables 232 | ``` 233 | grep "AcceptEnv" /etc/ssh/sshd_config 234 | ``` 235 | ### SSH looks up connections in DNS 236 | ``` 237 | grep "UseDNS" /etc/ssh/sshd_config 238 | ``` 239 | ### SSH uses privilege separation 240 | ``` 241 | grep "UsePrivilegeSeparation" /etc/ssh/sshd_config 242 | ``` 243 | ### .shosts used 244 | ``` 245 | find / -name .shosts -ls 246 | ``` 247 | ### shosts.equiv used 248 | ``` 249 | cat /etc/shosts.equiv 250 | ``` 251 | ### SSH allows .rhosts 252 | ``` 253 | grep "IgnoreRhosts" /etc/ssh/sshd_config 254 | ``` 255 | ### SSH public/private keys used 256 | ``` 257 | find / -name .ssh -type d -exec ls -la {} \; 258 | ``` 259 | ### SSH sessions are throttled 260 | ``` 261 | grep "MaxStartups" /etc/ssh/sshd_config 262 | ``` 263 | ### FTP users disallowed 264 | ``` 265 | cat /etc/ftpd/ftpusers 266 | ``` 267 | ### NFS shares 268 | ``` 269 | cat /etc/dfs/sharetab 270 | share -A 271 | ``` 272 | ### Secure consoles 273 | ``` 274 | grep "CONSOLE" /etc/default/login 275 | ``` 276 | ## Authentication 277 | Tags: authentication 278 | ### Banner 279 | ``` 280 | cat /etc/issue 281 | ``` 282 | ### MOTD 283 | ``` 284 | cat /etc/motd 285 | ``` 286 | ### Passwords 287 | ``` 288 | cat /etc/passwd 289 | cat /etc/shadow 290 | passwd -a -s | grep "NP" 291 | ``` 292 | ### SNMP community strings 293 | ``` 294 | grep "community" /etc/snmp/conf/snmpd.conf 295 | grep "community" /etc/net-snmp/conf/snmpd.conf 296 | ``` 297 | ### Login policy 298 | ``` 299 | cat /etc/default/login 300 | ``` 301 | ### Password aging 302 | ``` 303 | grep "WEEKS" /etc/default/passwd 304 | ``` 305 | ### Password minimum strength 306 | ``` 307 | cat /etc/default/passwd 308 | ``` 309 | ### Unlocked accounts 310 | ``` 311 | passwd -a -s | egrep -v "LK|NL" 312 | ``` 313 | ### Lock after retries 314 | ``` 315 | grep "LOCK_AFTER_RETRIES" /etc/security/policy.conf 316 | grep "RETRIES" /etc/default/login 317 | ``` 318 | ### Session timeout 319 | ``` 320 | grep "TMOUT" /etc/profile 321 | ``` 322 | ### SSH shows banner 323 | ``` 324 | grep "Banner" /etc/ssh/sshd_config 325 | ``` 326 | ### SSH shows MOTD 327 | ``` 328 | grep "PrintMotd" /etc/ssh/sshd_config 329 | ``` 330 | ### SSH allows empty passwords 331 | ``` 332 | grep "PermitEmptyPasswords" /etc/ssh/sshd_config 333 | ``` 334 | ## Cryptography 335 | Tags: cryptography 336 | ### known_hosts encrypted 337 | ``` 338 | grep "HashKnownHosts" /etc/ssh/ssh_config 339 | ``` 340 | ### SSH protocol 341 | ``` 342 | grep "Protocol" /etc/ssh/sshd_config 343 | ``` 344 | ### SSH protocol 1 key regeneration 345 | ``` 346 | grep "KeyRegenerationInterval" /etc/ssh/sshd_config 347 | ``` 348 | ### SSH protocol 1 key size 349 | ``` 350 | grep "ServerKeyBits" /etc/ssh/sshd_config 351 | ``` 352 | ### SSH protocol 2 public key authentication 353 | ``` 354 | grep "PubkeyAuthentication" /etc/ssh/sshd_config 355 | ``` 356 | ### SSH allows .rhosts with protocol 1 RSA 357 | ``` 358 | grep "RhostsRSAAuthentication" /etc/ssh/sshd_config 359 | ``` 360 | ### SSH allows protocol 1 RSA 361 | ``` 362 | grep "RSAAuthentication" /etc/ssh/sshd_config 363 | ``` 364 | ### SSH password based authentication 365 | ``` 366 | grep "PasswordAuthentication" /etc/ssh/sshd_config 367 | ``` 368 | ### SSH ciphers 369 | ``` 370 | grep "Ciphers" /etc/ssh/sshd_config 371 | ``` 372 | ### SSH MACs 373 | ``` 374 | grep "MACs" /etc/ssh/sshd_config 375 | ``` 376 | ### Blacklisted keys 377 | ``` 378 | grep "PermitBlacklistedKeys" /etc/ssh/sshd_config 379 | ``` 380 | ### Grub password obfuscated 381 | ``` 382 | grep "password" /path/to/menu.lst | grep "md5" 383 | ``` 384 | ### Crypto used for shadow 385 | ``` 386 | grep "CRYPT_DEFAULT" /etc/security/policy.conf 387 | ``` 388 | ### Crypto allowed for shadow 389 | ``` 390 | grep "CRYPT_ALGORITHMS_ALLOW" /etc/security/policy.conf 391 | ``` 392 | ## Software installed 393 | Tags: software-installed 394 | ### OS release 395 | ``` 396 | uname -r 397 | ``` 398 | ### Packages installed 399 | ``` 400 | pkginfo 401 | pkg list 402 | ``` 403 | ### Packages legit 404 | ``` 405 | pkg verify 406 | ``` 407 | ### Patches installed 408 | ``` 409 | showrev -p 410 | smpatch analyze 411 | ``` 412 | ### Processes 413 | ``` 414 | ps -aef 415 | ``` 416 | ### Services 417 | ``` 418 | svcs 419 | ``` 420 | ### Development tools 421 | ``` 422 | find / -type f \( -name perl -o -name gcc -o -name javac -o -name python -o -name ruby -o -name cc -o -name gdb -o -name mdb \) 423 | ``` 424 | ### 3rd party software 425 | ``` 426 | find /usr/local /opt -type f -ls 427 | ``` 428 | ## Logging 429 | Tags: logging 430 | ### Time synchronisation 431 | ``` 432 | grep "server" /etc/inet/ntp.conf 433 | ``` 434 | ### Remote logging 435 | ``` 436 | grep "@" /etc/syslog.conf 437 | ``` 438 | ### Cron logging 439 | ``` 440 | grep "CRONLOG" /etc/default/cron 441 | ``` 442 | ### Auditing 443 | ``` 444 | ps -aef | grep "auditd" 445 | ``` 446 | ## Resource limits 447 | Tags: resource-limits 448 | ### Running limits 449 | ``` 450 | ulimit -a 451 | ``` 452 | ### Tmp size 453 | ``` 454 | grep "swap" /etc/vfstab | grep "size" 455 | ``` 456 | ### Disk quotas 457 | ``` 458 | mount | grep "quota" 459 | ``` 460 | ## File permissions 461 | Tags: file-permissions 462 | ### Init umask 463 | ``` 464 | grep "CMASK" /etc/default/init 465 | ``` 466 | ### Root umask 467 | ``` 468 | grep "umask" /root/.profile 469 | ``` 470 | ### User umask 471 | ``` 472 | grep "umask" /etc/profile 473 | ``` 474 | ### Service umasks 475 | ``` 476 | grep "umask" /etc/init.d/* /etc/rc*.d/* 477 | ``` 478 | ### World readable files / directories 479 | ``` 480 | find / -perm -o+r -ls 481 | ``` 482 | ### World writable files / directories 483 | ``` 484 | find / -perm -o+w -ls 485 | ``` 486 | ### Group writable files / directories 487 | ``` 488 | find / -perm -o+w -ls 489 | ``` 490 | ### Unowned files / directories 491 | ``` 492 | find / -nouser -ls 493 | ``` 494 | ### Ungrouped files / directories 495 | ``` 496 | find / -nogroup -ls 497 | ``` 498 | ### Log files 499 | ``` 500 | ls -la /var/log /var/adm 501 | ``` 502 | ### SSH strict mode 503 | ``` 504 | grep "StrictModes" /etc/ssh/sshd_config 505 | ``` 506 | ### Root home 507 | ``` 508 | ls -ld `cat /etc/passwd | grep "root" | cut -f 6 -d ":"` 509 | ls -la /path/to/root 510 | ``` 511 | ### IPC 512 | ``` 513 | ipcs -A 514 | ``` 515 | ### Device policy 516 | ``` 517 | cat /etc/security/device_policy 518 | ``` 519 | ## Exploit mitigation 520 | Tags: exploit-mitigation 521 | ### Active mounts secure 522 | ``` 523 | mount | grep -v "noexec" 524 | mount | grep -v "nosetuid" 525 | mount | grep -v "nosuid" 526 | mount | grep -v "norstchown" 527 | ``` 528 | ### Configured mounts secure 529 | ``` 530 | grep -v "noexec" /etc/vfstab 531 | grep -v "nosetuid" /etc/vfstab 532 | grep -v "nosuid" /etc/vfstab 533 | grep -v "norstchown" /etc/vfstab 534 | ``` 535 | ### Separate partitions 536 | ``` 537 | mount 538 | ``` 539 | ### Cron users 540 | ``` 541 | cat /etc/cron.allow 542 | ``` 543 | ### At users 544 | ``` 545 | cat /etc/at.allow 546 | ``` 547 | ### Non executable stack 548 | ``` 549 | grep "noexec_user_stack" /etc/system 550 | ``` 551 | ### Stack randomisation 552 | ``` 553 | sxadm info 554 | ``` 555 | ### Randomised binaries 556 | ``` 557 | find / -type f \( -perm -u+s -o -perm -g+s \) | while read file 558 | do 559 | echo "File: $file" 560 | elfdump $file | grep "ASLR" 561 | done 562 | ``` 563 | ### Basic profile 564 | ``` 565 | grep "_GRANTED" /etc/security/policy.conf 566 | ``` 567 | ### Console profile 568 | ``` 569 | grep "CONSOLE_USER" /etc/security/policy.conf 570 | ``` 571 | ### Basic privs 572 | ``` 573 | grep "PRIV_DEFAULT" /etc/security/policy.conf 574 | ``` 575 | ### Priv limits 576 | ``` 577 | grep "PRIV_LIMIT" /etc/security/policy.conf 578 | ``` 579 | ## Privilege escalation 580 | Tags: privilege-escalation 581 | ### Init scripts run 582 | ``` 583 | cat /etc/inittab 584 | cat /etc/inittab | cut -f 4 -d: | cut -f 1 -d " " | while read file 585 | do 586 | echo "File: $file" 587 | ls -la $file 588 | done 589 | ``` 590 | ### At scripts run 591 | ``` 592 | for file in /var/spool/cron/atjobs/* 593 | do 594 | echo "File: $file" 595 | ls -l $file 596 | cat $file 597 | done 598 | ``` 599 | ### Cron scripts run 600 | ``` 601 | for file in /var/spool/cron/crontabs/* 602 | do 603 | echo "File: $file" 604 | ls -l $file 605 | cat $file 606 | done 607 | ``` 608 | ### Default path 609 | ``` 610 | grep "PATH" /etc/profile 611 | echo $PATH 612 | ``` 613 | ### User paths 614 | ``` 615 | grep "PATH" /etc/skel/.profile 616 | echo $PATH 617 | ``` 618 | ### Init paths 619 | ``` 620 | grep "PATH" /etc/init.d/* /etc/rc*.d 621 | ``` 622 | ### Default linker path 623 | ``` 624 | grep "LD_LIBRARY_PATH" /etc/profile 625 | echo $LD_LIBRARY_PATH 626 | ``` 627 | ### User linker paths 628 | ``` 629 | grep "LD_LIBRARY_PATH" /etc/skel/.profile 630 | ``` 631 | ### Init linker paths 632 | ``` 633 | grep "LD_LIBRARY_PATH" /etc/init.d/* /etc/rc*.d 634 | ``` 635 | ### SetUID files 636 | ``` 637 | find / -perm -u+s -type f -ls 638 | ``` 639 | ### SetGID files 640 | ``` 641 | find / -perm -g+s -type f -ls 642 | ``` 643 | ### Sudo configuration 644 | ``` 645 | cat /etc/sudoers 646 | for file in /etc/sudoers.d/* 647 | do 648 | echo "File: $file" 649 | cat $file 650 | done 651 | ``` 652 | ### Roles 653 | ``` 654 | cat /etc/user_attr 655 | cat /etc/passwd | cut -f 1 -d ":" | while read user 656 | do 657 | echo "User: $user" 658 | roles $user 659 | done 660 | ``` 661 | ### Profiles 662 | ``` 663 | cat /etc/security/prof_attr 664 | for file in /etc/security/prof_attr.d/* 665 | do 666 | echo "File: $file" 667 | cat $file 668 | done 669 | ``` 670 | ### Command profiles 671 | ``` 672 | cat /etc/security/exec_attr 673 | for file in /etc/security/exec_attr.d/* 674 | do 675 | echo "File: $file" 676 | cat $file 677 | done 678 | ``` 679 | ## Common services 680 | Tags: common-services 681 | ### SSH running config 682 | ``` 683 | sshd -T 684 | ``` 685 | ### Web server config 686 | ``` 687 | find / -name httpd.conf | while read file 688 | do 689 | echo "File: $file" 690 | ls -l $file 691 | cat $file 692 | done 693 | ``` 694 | ### Web server cgi-bin 695 | ``` 696 | find /usr/lib -name cgi-bin | while read file 697 | do 698 | echo "File: $file" 699 | ls -l $file 700 | done 701 | -------------------------------------------------------------------------------- /compare/README.md: -------------------------------------------------------------------------------- 1 | # Compare Mode 2 | 3 | This directory contains example files for the "compare" mode of unix-audit. 4 | 5 | The purpose of "compare" mode is to highlight when audit commands are missing for a particular platform. 6 | 7 | An example command line to generate a compare report is: 8 | 9 | ``` 10 | python unix-audit.py compare ./checks-database/ all all > compare/comparison.md 11 | ``` 12 | 13 | Consider reports in this directory to be samples only. They are not guaranteed to reflect the latest checks database. 14 | -------------------------------------------------------------------------------- /compare/comparison.md: -------------------------------------------------------------------------------- 1 | | Check Title | aix | linux | solaris | 2 | | --- | --- | --- | --- | 3 | | Access control > .netrc used | Yes | Yes | Yes | 4 | | Access control > .rhosts used | Yes | Yes | Yes | 5 | | Access control > .shosts used | Yes | Yes | Yes | 6 | | Access control > Account statuses | No | Yes | No | 7 | | Access control > Accounts with non-standard shells | Yes | Yes | Yes | 8 | | Access control > FTP users disallowed | Yes | Yes | Yes | 9 | | Access control > Firewall configured | Yes | Yes | Yes | 10 | | Access control > NFS shares | Yes | Yes | Yes | 11 | | Access control > Remote X | Yes | Yes | Yes | 12 | | Access control > SMB shares | No | Yes | No | 13 | | Access control > SSH ACLs configured | Yes | Yes | Yes | 14 | | Access control > SSH TCP forwarding | Yes | Yes | Yes | 15 | | Access control > SSH VPN | Yes | Yes | Yes | 16 | | Access control > SSH X11 forwarding | Yes | Yes | Yes | 17 | | Access control > SSH accepts environment variables | Yes | Yes | Yes | 18 | | Access control > SSH agent forwarding | Yes | Yes | Yes | 19 | | Access control > SSH allows .rhosts | Yes | Yes | Yes | 20 | | Access control > SSH binds X11 to localhost | Yes | Yes | Yes | 21 | | Access control > SSH gateway ports | Yes | Yes | Yes | 22 | | Access control > SSH looks up connections in DNS | Yes | Yes | Yes | 23 | | Access control > SSH public/private keys used | Yes | Yes | Yes | 24 | | Access control > SSH reads environment from user file | Yes | Yes | Yes | 25 | | Access control > SSH root logins | Yes | Yes | Yes | 26 | | Access control > SSH sessions are throttled | Yes | Yes | Yes | 27 | | Access control > SSH user logins | Yes | Yes | Yes | 28 | | Access control > SSH uses privilege separation | Yes | Yes | Yes | 29 | | Access control > Secure consoles | Yes | Yes | Yes | 30 | | Access control > TCP wrappers used | Yes | Yes | Yes | 31 | | Access control > Valid shells | Yes | Yes | Yes | 32 | | Access control > X root logins | No | Yes | No | 33 | | Access control > hosts.equiv used | Yes | Yes | Yes | 34 | | Access control > shosts.equiv used | Yes | Yes | Yes | 35 | | Authentication > Active Directory enabled | No | Yes | No | 36 | | Authentication > Banner | Yes | Yes | Yes | 37 | | Authentication > Lock after retries | No | No | Yes | 38 | | Authentication > Login PAM | No | Yes | No | 39 | | Authentication > Login policy | Yes | No | Yes | 40 | | Authentication > MOTD | Yes | Yes | Yes | 41 | | Authentication > Non-local users | No | Yes | No | 42 | | Authentication > Password aging | Yes | Yes | Yes | 43 | | Authentication > Password minimum strength | Yes | Yes | Yes | 44 | | Authentication > Passwords | Yes | Yes | Yes | 45 | | Authentication > SNMP community strings | Yes | Yes | Yes | 46 | | Authentication > SSH allows empty passwords | Yes | Yes | Yes | 47 | | Authentication > SSH shows MOTD | Yes | Yes | Yes | 48 | | Authentication > SSH shows banner | Yes | Yes | Yes | 49 | | Authentication > SSH uses PAM | No | Yes | No | 50 | | Authentication > Session timeout | Yes | Yes | Yes | 51 | | Authentication > Su PAM | No | Yes | No | 52 | | Authentication > Sudo PAM | No | Yes | No | 53 | | Authentication > System Auth PAM | No | Yes | No | 54 | | Authentication > Unlocked accounts | Yes | Yes | Yes | 55 | | Authentication > Using Kerberos | No | Yes | No | 56 | | Authentication > Using LDAP | No | Yes | No | 57 | | Authentication > Using NIS | No | Yes | No | 58 | | Common services > SSH client config | No | Yes | No | 59 | | Common services > SSH config | No | Yes | No | 60 | | Common services > SSH running config | Yes | Yes | Yes | 61 | | Common services > Web server cgi-bin | Yes | Yes | Yes | 62 | | Common services > Web server config | Yes | Yes | Yes | 63 | | Common services > Web server logs | No | Yes | No | 64 | | Cryptography > Blacklisted keys | Yes | Yes | Yes | 65 | | Cryptography > Crypto allowed for shadow | No | No | Yes | 66 | | Cryptography > Crypto used for shadow | Yes | Yes | Yes | 67 | | Cryptography > Grub password obfuscated | No | Yes | Yes | 68 | | Cryptography > SSH MACs | Yes | Yes | Yes | 69 | | Cryptography > SSH allows .rhosts with protocol 1 RSA | Yes | Yes | Yes | 70 | | Cryptography > SSH allows protocol 1 RSA | Yes | Yes | Yes | 71 | | Cryptography > SSH ciphers | Yes | Yes | Yes | 72 | | Cryptography > SSH password based authentication | Yes | Yes | Yes | 73 | | Cryptography > SSH protocol | Yes | Yes | Yes | 74 | | Cryptography > SSH protocol 1 key regeneration | Yes | Yes | Yes | 75 | | Cryptography > SSH protocol 1 key size | Yes | Yes | Yes | 76 | | Cryptography > SSH protocol 2 public key authentication | Yes | Yes | Yes | 77 | | Cryptography > Trusted CAs | No | Yes | No | 78 | | Cryptography > Trusted keyrings | No | Yes | No | 79 | | Cryptography > known_hosts encrypted | Yes | Yes | Yes | 80 | | Environment > Active kernel hardening | No | Yes | No | 81 | | Environment > Boot flags | No | Yes | No | 82 | | Environment > Containers | No | Yes | No | 83 | | Environment > Ctrl-alt-delete | No | Yes | No | 84 | | Environment > Currently logged in | No | Yes | No | 85 | | Environment > Environment variables set | No | Yes | No | 86 | | Environment > Grub password set | No | Yes | Yes | 87 | | Environment > Host is KVM | No | Yes | No | 88 | | Environment > Host is VMware | No | Yes | No | 89 | | Environment > Host is VirtualBox | No | Yes | No | 90 | | Environment > Host is Xen | No | Yes | No | 91 | | Environment > Host is container | No | Yes | No | 92 | | Environment > K8s cluster | No | Yes | No | 93 | | Environment > Kernel config | No | Yes | No | 94 | | Environment > Kernel debugging | No | Yes | No | 95 | | Environment > Kernel hardening | No | Yes | No | 96 | | Environment > Kernel logs | No | Yes | No | 97 | | Environment > Kernel modules | No | Yes | No | 98 | | Environment > Kernel modules supported | No | Yes | No | 99 | | Environment > Loaded kernel modules | No | Yes | Yes | 100 | | Environment > Logins | No | Yes | No | 101 | | Environment > OBP banner set | No | No | Yes | 102 | | Environment > OBP password set | No | No | Yes | 103 | | Environment > PCI cards accessible | Yes | Yes | Yes | 104 | | Environment > Stop-A | No | No | Yes | 105 | | Environment > USB peripherals accessible | Yes | Yes | Yes | 106 | | Environment > Zones | No | No | Yes | 107 | | Exploit mitigation > Active mounts secure | Yes | Yes | Yes | 108 | | Exploit mitigation > AppArmour policy | No | Yes | No | 109 | | Exploit mitigation > AppArmour processes | No | Yes | No | 110 | | Exploit mitigation > AppArmour supported | No | Yes | No | 111 | | Exploit mitigation > At users | Yes | Yes | Yes | 112 | | Exploit mitigation > Basic privs | No | No | Yes | 113 | | Exploit mitigation > Basic profile | No | No | Yes | 114 | | Exploit mitigation > Configured mounts secure | Yes | Yes | Yes | 115 | | Exploit mitigation > Console profile | No | No | Yes | 116 | | Exploit mitigation > Cron users | Yes | Yes | Yes | 117 | | Exploit mitigation > Non executable stack | Yes | Yes | Yes | 118 | | Exploit mitigation > PTrace scope | No | Yes | No | 119 | | Exploit mitigation > Priv limits | No | No | Yes | 120 | | Exploit mitigation > Randomised binaries | No | No | Yes | 121 | | Exploit mitigation > SELinux policy | No | Yes | No | 122 | | Exploit mitigation > SELinux processes | No | Yes | No | 123 | | Exploit mitigation > SELinux running | No | Yes | No | 124 | | Exploit mitigation > SELinux supported | No | Yes | No | 125 | | Exploit mitigation > Separate partitions | Yes | Yes | Yes | 126 | | Exploit mitigation > SetUID debug | No | Yes | No | 127 | | Exploit mitigation > Stack randomisation | No | Yes | Yes | 128 | | Exploit mitigation > Stack smashing protection | No | Yes | No | 129 | | File permissions > Device policy | No | No | Yes | 130 | | File permissions > FTP umask | Yes | No | No | 131 | | File permissions > Group writable files / directories | Yes | Yes | Yes | 132 | | File permissions > IPC | No | No | Yes | 133 | | File permissions > Init umask | Yes | Yes | Yes | 134 | | File permissions > Log files | Yes | Yes | Yes | 135 | | File permissions > Root home | Yes | Yes | Yes | 136 | | File permissions > Root umask | Yes | Yes | Yes | 137 | | File permissions > SSH strict mode | Yes | Yes | Yes | 138 | | File permissions > Service umasks | Yes | Yes | Yes | 139 | | File permissions > Syslog umask | No | Yes | No | 140 | | File permissions > Ungrouped files / directories | Yes | Yes | Yes | 141 | | File permissions > Unowned files / directories | Yes | Yes | Yes | 142 | | File permissions > User homes | No | Yes | No | 143 | | File permissions > User umask | Yes | Yes | Yes | 144 | | File permissions > World readable files / directories | Yes | Yes | Yes | 145 | | File permissions > World writable files / directories | Yes | Yes | Yes | 146 | | Important file locations > Configs | No | Yes | No | 147 | | Important file locations > Core files | No | Yes | No | 148 | | Important file locations > Logs | No | Yes | No | 149 | | Important file locations > SetUID and setGIDs files | No | Yes | No | 150 | | Important file locations > Temporary locations | No | Yes | No | 151 | | Informational > Date | No | Yes | No | 152 | | Informational > Hostname | Yes | Yes | Yes | 153 | | Informational > Kernel version | Yes | Yes | Yes | 154 | | Informational > Network interfaces | Yes | Yes | Yes | 155 | | Informational > Running as | No | Yes | No | 156 | | Logging > Auditd policy | No | Yes | No | 157 | | Logging > Auditing | No | Yes | Yes | 158 | | Logging > Cron logging | Yes | Yes | Yes | 159 | | Logging > Remote logging | Yes | Yes | Yes | 160 | | Logging > Syslog process | No | Yes | No | 161 | | Logging > Syslog with rsyslog | No | Yes | No | 162 | | Logging > Syslog with syslog-ng | No | Yes | No | 163 | | Logging > Time synchronisation | Yes | Yes | Yes | 164 | | Logging > User histories | No | Yes | No | 165 | | Network stack tuning > Directed broadcasts | No | No | Yes | 166 | | Network stack tuning > Echo broadcasts | No | No | Yes | 167 | | Network stack tuning > Generic tuning - we should break this down and cross reference OS | No | No | Yes | 168 | | Network stack tuning > IP forwarding | Yes | Yes | Yes | 169 | | Network stack tuning > Netmask broadcasts | No | No | Yes | 170 | | Network stack tuning > Network shares mounted | No | Yes | No | 171 | | Network stack tuning > Redirects | No | No | Yes | 172 | | Network stack tuning > Source routing | No | No | Yes | 173 | | Network stack tuning > Strict multihoming | No | No | Yes | 174 | | Network stack tuning > Strong ISS | No | No | Yes | 175 | | Network stack tuning > Syncookies | No | Yes | No | 176 | | Network stack tuning > TCP limits | No | No | Yes | 177 | | Network stack tuning > Timestamp broadcasts | No | No | Yes | 178 | | Networking > ARP | Yes | Yes | Yes | 179 | | Networking > DNS | Yes | Yes | Yes | 180 | | Networking > Hosts | Yes | Yes | Yes | 181 | | Networking > IPv6 | Yes | Yes | Yes | 182 | | Networking > Internet | Yes | Yes | Yes | 183 | | Networking > Internet by proxy | No | Yes | No | 184 | | Networking > Listening services | Yes | Yes | Yes | 185 | | Networking > Name services | Yes | Yes | Yes | 186 | | Networking > Network traffic | No | Yes | No | 187 | | Networking > RPC services | No | Yes | No | 188 | | Networking > Routing | Yes | Yes | Yes | 189 | | Networking > Web accessible | No | Yes | No | 190 | | Privilege escalation > At scripts run | Yes | Yes | Yes | 191 | | Privilege escalation > Command profiles | No | No | Yes | 192 | | Privilege escalation > Cron scripts run | Yes | Yes | Yes | 193 | | Privilege escalation > Default linker path | Yes | Yes | Yes | 194 | | Privilege escalation > Default path | Yes | Yes | Yes | 195 | | Privilege escalation > Init linker paths | Yes | Yes | Yes | 196 | | Privilege escalation > Init paths | Yes | Yes | Yes | 197 | | Privilege escalation > Init scripts run | Yes | Yes | Yes | 198 | | Privilege escalation > Insecure RPATHs | No | Yes | No | 199 | | Privilege escalation > POSIX shared memory | No | Yes | No | 200 | | Privilege escalation > Proc tree | No | Yes | No | 201 | | Privilege escalation > Processes with open files | No | Yes | No | 202 | | Privilege escalation > Profiles | No | No | Yes | 203 | | Privilege escalation > Roles | No | No | Yes | 204 | | Privilege escalation > SetGID files | Yes | Yes | Yes | 205 | | Privilege escalation > SetUID files | Yes | Yes | Yes | 206 | | Privilege escalation > Sudo configuration | Yes | Yes | Yes | 207 | | Privilege escalation > Sys tree | No | Yes | No | 208 | | Privilege escalation > System V shared memory | No | Yes | No | 209 | | Privilege escalation > UNIX sockets | No | Yes | No | 210 | | Privilege escalation > User capabilities | No | Yes | No | 211 | | Privilege escalation > User linker paths | Yes | Yes | Yes | 212 | | Privilege escalation > User paths | Yes | Yes | Yes | 213 | | Resource limits > Configured limits | Yes | Yes | No | 214 | | Resource limits > Disk quotas | Yes | Yes | Yes | 215 | | Resource limits > Running limits | Yes | Yes | Yes | 216 | | Resource limits > Tmp size | No | Yes | Yes | 217 | | Software installed > 3rd party software | Yes | Yes | Yes | 218 | | Software installed > Development tools | Yes | Yes | Yes | 219 | | Software installed > OS release | Yes | Yes | Yes | 220 | | Software installed > Package management | No | Yes | No | 221 | | Software installed > Packages for NOPC | No | Yes | No | 222 | | Software installed > Packages installed | Yes | Yes | Yes | 223 | | Software installed > Packages legit | No | No | Yes | 224 | | Software installed > Patches installed | No | No | Yes | 225 | | Software installed > Processes | Yes | Yes | Yes | 226 | | Software installed > Services | Yes | Yes | Yes | 227 | | Software installed > Systemd configs | No | Yes | No | 228 | | Software installed > Systemd services | No | Yes | No | 229 | -------------------------------------------------------------------------------- /doc/AUTHORS: -------------------------------------------------------------------------------- 1 | Tim Brown , original source material for AIX, Solaris and Linux 2 | Mark Lowe, Python code and general modernisation 3 | -------------------------------------------------------------------------------- /doc/ChangeLog: -------------------------------------------------------------------------------- 1 | 2023-07-29 unix-audit main 2 | 3 | * Merge pull request #4 from jenslink/main 4 | * Added IPv6 checks 5 | * Added doc/ChangeLog, doc/TODO 6 | * Updated unix-audit.py to include hashbang 7 | * Reformatted doc/TODO 8 | * Updated audit-scripts/linux-audit.sh 9 | 10 | -- Tim Brown 11 | 12 | 2023-07-28 unix-audit main 13 | 14 | * Reviewed and updated COPYING to LICENSE in line with Cisco's open source policies 15 | * Updated audit-scripts/linux-audit.sh, audit-scripts/solaris-audit.sh, 16 | audit-scripts/aix-audit.sh 17 | 18 | -- Mark Lowe 19 | 20 | 2023-07-26 unix-audit main 21 | 22 | * Merged pull request #1 from jenslink/main 23 | * Added ip commands in addition to old style ifconfig / arp / netstat for Linux 24 | * Merged pull request #2 from jenslink/main 25 | * Added ip commands in addition to old style ifconfig / arp / netstat 26 | 27 | -- Tim Brown 28 | 29 | 2023-07-25 unix-audit main 30 | 31 | * Reviewed and updated LICENSE to COPYING 32 | * The original proof of concept for this code predates Cisco and was onboarded 33 | as part of the Portcullis acquisition. As such it was included in 34 | intellectual property covered under the original contributor acquisition 35 | terms 36 | * Added doc/AUTHORS 37 | 38 | -- Tim Brown 39 | 40 | 2023-07-12 unix-audit main 41 | 42 | * Updated CONTRIBUTING.md, README.md 43 | * Reviewed and updated COPYING to LICENSE 44 | 45 | -- Mark Lowe 46 | 47 | 2023-07-10 unix-audit main 48 | 49 | * Reviewed and updated LICENSE to COPYING 50 | 51 | -- Tim Brown 52 | 53 | 2023-07-10 unix-audit main 54 | 55 | * Created CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md 56 | * Updated README.md 57 | * Replaced generate-audit-script.py with unix-audit.py 58 | * Generated audit-scripts/linux-audit.sh, audit-scripts/solaris-audit.sh, 59 | audit-scripts/aix-audit.sh 60 | * Created compare/comparison.md 61 | 62 | -- Mark Lowe 63 | 64 | 2023-07-06 unix-audit main 65 | 66 | * Created checks-database/linux.md, checks-database/solaris.md, 67 | checks-database/linux.md 68 | * Created generate-audit-script.py 69 | * Created README.md, LICENSE 70 | 71 | -- Mark Lowe 72 | 73 | 2020-08-08 portcullis-*.sh 2016-12 - 2020-08 74 | 75 | * Work in CX APT private repository (operating_system_build_review@various) 76 | * Updates by twadhwab 77 | * Linux changes 78 | * Added lots of new data sources 79 | * Date 80 | * Running as 81 | * Boot flags 82 | * Kernel logs 83 | * Kernel config 84 | * Kernel hardening 85 | * Active kernel hardening 86 | * Host is KVM 87 | * Host is VMware 88 | * Host is VirtualBox 89 | * Host is Xen 90 | * Host is container 91 | * Containers 92 | * K8s cluster 93 | * Environment variables set 94 | * Currently logged in 95 | * Logins 96 | * Web accessible 97 | * Internet by proxy 98 | * RPC services 99 | * Network shares mounted 100 | * Account statuses 101 | * SMB shares 102 | * Active Directory enabled 103 | * Non-local users 104 | * Using NIS 105 | * Using Kerberos 106 | * Using LDAP 107 | * Trusted CAs 108 | * Trusted keyrings 109 | * Packages for NOPC 110 | * Package management 111 | * Systemd services 112 | * Systemd configs 113 | * Syslog process 114 | * Syslog with rsyslog 115 | * Syslog with syslog-ng 116 | * User histories 117 | * Auditing 118 | * Auditd policy 119 | * User homes 120 | * AppArmour supported 121 | * AppArmour policy 122 | * AppArmour processes 123 | * SetUID debug 124 | * PTrace scope 125 | * User capabilities 126 | * Default path 127 | * User paths 128 | * Init paths 129 | * Default linker path 130 | * User linker paths 131 | * Init linker paths 132 | * SetUID files 133 | * SetGID files 134 | * Sudo configuration 135 | * Insecure RPATHs 136 | * Processes with open files 137 | * Proc tree 138 | * Sys tree 139 | * POSIX shared memory 140 | * System V shared memory 141 | * UNIX sockets 142 | * SSH config 143 | * SSH client config 144 | * Web server config 145 | * Logs 146 | * SetUID and setGIDs files 147 | * Temporary locations 148 | * Core files 149 | * Added FXB's tweaks to gather network traffic 150 | * Various bug fixes 151 | * AIX changes 152 | * A couple more bug fixed 153 | 154 | -- Tim Brown 155 | 156 | 2016-12-07 portcullis-*.sh 2004 - 2016 157 | 158 | * Import of code from Portcullis Labs private repository (build-reviews@11936) 159 | * Initial work by TMB 160 | * Linux changes 161 | * Added SSH running config, web server config, web server cgi-bin 162 | * Added SELinux processes 163 | * Tweaked kernel module checks 164 | * Added Internet 165 | * Various bug fixes 166 | * Solaris changes 167 | * Added SSH running config, web server config, web server cgi-bin 168 | * Added Internet 169 | * Added Stack randomisation, randomised binaries, packages legit, crypto allowed for shadow, basic privs, priv limits, lock after retries, directed broadcasts, echo broadcasts, TCP limits, strong ISS, source routing, timestamp broadcasts, netmask broadcasts, redirects, zones, roles, profiles, auditing, device policy, command profiles, basic profile, console profile, strict multihoming 170 | * Updated Network stack tuning to cover IPv6 for all, updated packages installed, active mounts secure, configured mounts secure 171 | * Cleaned up for/while loops 172 | * Cleaned up cat/grep usage 173 | * Various bug fixes 174 | * AIX changes 175 | * Added SSH running config, web server config, web server cgi-bin 176 | * Added Internet 177 | * Various bug fixes 178 | * Merged RGH's VIOS notes 179 | 180 | -- Tim Brown 181 | -------------------------------------------------------------------------------- /doc/TODO: -------------------------------------------------------------------------------- 1 | * Convert what can i.. to unix-audit checks 2 | * Convert badrpath.sh to to unix-audit checks 3 | * Solaris 4 | * PAM 5 | * Passworded console 6 | * Audit flags 7 | * Per account locking 8 | * AIX 9 | * AIX VIO Servers use a padmin console, to limit the privileges/commands available for (mis)use; similar to the enable command on Cisco devices 10 | * Run AIX/VIOS Command with padmin/root Privileges in VIO Server 11 | * Login as user padmin into VIO server: padmin/ 12 | * Now you can run any AIX command at the padmin console without jumping to root like so: print "lsvg -l rootvg" | oem_setup_env 13 | * To gain root access on VIO server like so: oem_setup_env 14 | * You run lsmap -all VIOS command like so: /usr/ios/cli/ioscli lsmap -all 15 | * By default the ioscli commands are not available for the root user. All ioscli commands are in fact calls of /usr/ios/cli/ioscli with the command as argument. So you can use all ioscli commands as user root by appending /usr/ios/cli/ioscli in front of the command 16 | -------------------------------------------------------------------------------- /unix-audit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | import os 5 | import re 6 | 7 | wildcards = ["*", "any", "all"] 8 | 9 | class Command: 10 | def __init__(self, title: str): 11 | self.title = title 12 | self.tags = [] 13 | self.platform_tags = [] 14 | self.code_block = "" 15 | 16 | def append(self, line: str): 17 | self.code_block = self.code_block + line 18 | 19 | def __str__(self): 20 | return f"Title: {self.title}\nTags: {self.tags}\nPlatformTags: {self.platform_tags}\nCode: {self.code_block}" 21 | 22 | class Commands: 23 | def __init__(self): 24 | self.commands = [] # list of Command objects 25 | 26 | def add_or_get(self, title: str): 27 | for command in self.commands: 28 | if command.title == title: 29 | return command 30 | 31 | command = Command(title) 32 | self.commands.append(command) 33 | return command 34 | 35 | def get_platforms(self): 36 | platforms = set() 37 | for command in self.commands: 38 | for platform in command.platform_tags: 39 | platforms.add(platform) 40 | return platforms 41 | 42 | def find_title(self, title: str): 43 | for command in self.commands: 44 | if command.title == title: 45 | return command 46 | return None 47 | 48 | def find(self, platform: str, tags: list): # Lists of strings 49 | found_commands_list = [] 50 | 51 | for command in self.commands: 52 | applicable_platform = False 53 | if command.platform_tags: 54 | # check if platform is a wildcard 55 | if platform in wildcards: 56 | applicable_platform = True 57 | 58 | # check if platform matches platform for command 59 | elif platform in command.platform_tags: 60 | applicable_platform = True 61 | if applicable_platform: 62 | applicable_tag = False 63 | if command.tags: 64 | # check if tag is a wildcard 65 | if any([tag in wildcards for tag in tags]): 66 | applicable_tag = True 67 | 68 | # check if tag matches tag for command 69 | elif any([tag in command.tags for tag in tags]): 70 | applicable_tag = True 71 | 72 | if applicable_tag: 73 | found_commands_list.append(command) 74 | 75 | found_commands = Commands() 76 | found_commands.commands = found_commands_list 77 | return found_commands 78 | 79 | def get_tags(self): 80 | tags = set() 81 | for command in self.commands: 82 | for tag in command.tags: 83 | tags.add(tag) 84 | return tags 85 | 86 | def __str__(self): 87 | return "\n".join([str(command) for command in self.commands]) 88 | 89 | def __iter__(self): 90 | return iter(self.commands) 91 | 92 | def get_script(self): 93 | script = "" 94 | for command in self.commands: 95 | script = script + f"echo \"=== {command.title}\"===\n" 96 | script = script + command.code_block + "\n" 97 | return script 98 | 99 | def count(self): 100 | return len(self.commands) 101 | 102 | def load_from_directory(self, database_dir: str): 103 | # check if directory exists 104 | if not os.path.isdir(database_dir): 105 | print(f"[E] Database directory not found: {database_dir}. Run with no args for help.") 106 | sys.exit(1) 107 | 108 | #print(f"[I] Loading commands from database directory: {database_dir}") 109 | 110 | # print number of .md files in directory 111 | num_files = len([filename for filename in os.listdir(database_dir) if filename.endswith(".md")]) 112 | #print(f"[I] Found {num_files} .md files in database directory. Parsing...") 113 | 114 | for filename in os.listdir(database_dir): 115 | if filename.endswith(".md"): 116 | #print(f"[I] Reading database file {filename}") 117 | with open(os.path.join(database_dir, filename), 'r') as infile: 118 | current_tags_dict = {} 119 | current_platform_tags_dict = {} 120 | section_title = {} 121 | level = None 122 | state = "outside_code_section" 123 | for line in infile.readlines(): 124 | line = line.rstrip() 125 | 126 | m = re.match(r'^(#+)\s*(.*?)\s*$', line) 127 | if state == "outside_code_section" and m: # need to be careful to ignore shell commends in code blocks 128 | level = len(m.group(1)) 129 | section_title[level] = m.group(2) 130 | state = "outside_code_section" 131 | continue 132 | 133 | # check if line is like: PlatformTags: linux 134 | m = re.match(r'^\s*PlatformTag:\s*(.*?)\s*$', line) 135 | if m: 136 | platform_tags_string = m.group(1) 137 | current_platform_tags_dict[level] = [tag.strip() for tag in platform_tags_string.split(',')] 138 | continue 139 | 140 | # Tags: line 141 | m = re.match(r'^\s*Tags:\s*(.*?)\s*$', line) 142 | if m: 143 | tags_string = m.group(1) 144 | current_tags_dict[level] = [tag.strip() for tag in tags_string.split(',')] 145 | continue 146 | 147 | # code block boundary 148 | m = re.match(r'^\s*```\s*$', line) 149 | if m: 150 | if state == "outside_code_section": 151 | state = "in_code_section" 152 | continue 153 | 154 | if state == "in_code_section": 155 | state = "outside_code_section" 156 | continue 157 | 158 | if state == "outside_code_section": 159 | #print(f"[D] Ignoring: {line}") 160 | continue 161 | 162 | if state == "in_code_section": 163 | # Save command from code block 164 | current_title = None 165 | current_tags_list = [] 166 | current_platform_tags_list = [] 167 | 168 | for l in range(1, level+1): 169 | if l in current_tags_dict: 170 | current_tags_list = current_tags_list + current_tags_dict[l] 171 | 172 | if l in current_platform_tags_dict: 173 | current_platform_tags_list = current_platform_tags_list + current_platform_tags_dict[l] 174 | 175 | if current_title is None: 176 | current_title = section_title[l] 177 | else: 178 | current_title = current_title + " > " + section_title[l] 179 | 180 | command = self.add_or_get(current_title) 181 | command.append(f"{line}\n") 182 | command.tags = current_tags_list 183 | command.platform_tags = current_platform_tags_list 184 | continue 185 | 186 | # Raise exception. Should never get here 187 | raise Exception(f"Unexpected state: {state}") 188 | 189 | #print(f"[I] Parsed {len(self.commands)} commands so far...") 190 | 191 | def get_titles(self): 192 | titles = set() 193 | for command in self.commands: 194 | titles.add(command.title) 195 | return set(sorted(titles)) 196 | 197 | 198 | def usage(): 199 | print("Usage: unix-audit.py mode args") 200 | print("") 201 | print("Modes:") 202 | print(" python3 unix-audit.py list ") 203 | print(" python3 unix-audit.py generate ") 204 | print(" python3 unix-audit.py compare ") 205 | print("") 206 | print("List mode - lists the platforms and tags available for other modes. Examples:") 207 | print("") 208 | print(" python3 unix-audit.py list ./checks-database/") 209 | print("") 210 | print("Generate mode - used to generate an audit script from md files. Examples:") 211 | print("") 212 | print(" python3 unix-audit.py generate ./checks-database/ linux all > audit-scripts/linux-audit.sh") 213 | print(" python3 unix-audit.py generate ./checks-database/ aix all > audit-scripts/aix-audit.sh") 214 | print(" python3 unix-audit.py generate ./checks-database/ solaris all > audit-scripts/solaris-audit.sh") 215 | print("") 216 | print("Compare mode - find differences in commands for 2 or more platforms. Examples:") 217 | print("") 218 | print(" python unix-audit.py compare ./checks-database/ all all > compare/comparison.md") 219 | print(" python3 unix-audit.py compare ./checks-database/ linux,solaris > linux-solaris-compare.md") 220 | print(" python3 unix-audit.py compare ./checks-database/ all authentication,logging > linux-solaris-compare.md") 221 | print("") 222 | 223 | 224 | if __name__ == "__main__": 225 | # parse mode as first command line arg 226 | if len(sys.argv) < 2: 227 | print("[E] Missing mode. Specify 'generate', 'list', or 'compare' as first argument.") 228 | usage() 229 | sys.exit(1) 230 | 231 | mode = sys.argv[1] 232 | 233 | if mode not in ["generate", "list", "compare"]: 234 | print("[E] Invalid mode. Specify 'generate', 'list', or 'compare' as first argument.") 235 | usage() 236 | sys.exit(1) 237 | 238 | # parse database directory as second command line arg 239 | if len(sys.argv) < 3: 240 | print("[E] Missing database directory. Specify database directory as second argument.") 241 | usage() 242 | sys.exit(1) 243 | 244 | database_dir = sys.argv[2] 245 | available_commands = Commands() 246 | available_commands.load_from_directory(database_dir) 247 | 248 | if available_commands.count() == 0: 249 | print(f"[E] No commands found in database directory: {database_dir}. Check md files are present and formatted correctly.") 250 | usage() 251 | sys.exit(1) 252 | 253 | if mode == "list": 254 | print(f"Available platforms: {', '.join(available_commands.get_platforms())}") 255 | print(f"Available tags: {', '.join(available_commands.get_tags())}") 256 | sys.exit(0) 257 | 258 | # "generate" and "compare" modes take same arguments 259 | 260 | # parse platform tag as third command line arg 261 | if len(sys.argv) < 4: 262 | print("[E] Missing platform tag. Specify platform tag as third argument.") 263 | usage() 264 | sys.exit(1) 265 | 266 | platform_tags_string = sys.argv[3] 267 | platform_tags = platform_tags_string.split(',') 268 | 269 | # check if each supplied platform_tag is valid in database or is a wildcard 270 | for platform_tag in platform_tags: 271 | if platform_tag not in available_commands.get_platforms() and platform_tag not in wildcards: 272 | print(f"[E] Invalid platform tag: {platform_tag}") 273 | print(f"Available platforms: {', '.join(available_commands.get_platforms())}") 274 | sys.exit(1) 275 | 276 | # parse other tags as fourth command line arg 277 | if len(sys.argv) < 5: 278 | print("[E] Missing other tags. Specify other tags as fourth argument.") 279 | usage() 280 | sys.exit(1) 281 | 282 | other_tags = sys.argv[4].split(',') 283 | 284 | # check if each supplied other_tag is valid in database or is a wildcard 285 | for tag in other_tags: 286 | if tag not in available_commands.get_tags() and tag not in wildcards: 287 | print(f"[E] Invalid tag: {tag}") 288 | print(f"Available tags: {', '.join(available_commands.get_tags())}") 289 | usage() 290 | sys.exit(1) 291 | 292 | if mode == "generate": 293 | selected_commands = available_commands.find(platform_tags_string, other_tags) 294 | # print(str(selected_commands)) 295 | print(selected_commands.get_script()) 296 | sys.exit(0) 297 | 298 | if mode == "compare": 299 | selected_commands = {} 300 | titles = {} 301 | 302 | if platform_tags_string in wildcards: 303 | platform_tags = sorted(list(available_commands.get_platforms())) 304 | 305 | platform_count = len(platform_tags) 306 | 307 | for platform_tag in platform_tags: 308 | selected_commands[platform_tag] = available_commands.find(platform_tag, other_tags) 309 | titles[platform_tag] = selected_commands[platform_tag].get_titles() 310 | 311 | # strip off first field delimited with >. This is the platform name. 312 | titles[platform_tag] = set([">".join(title.split(">")[1:]).lstrip() for title in titles[platform_tag]]) 313 | 314 | union = set() 315 | 316 | for platform_tag in platform_tags: 317 | union = union.union(titles[platform_tag]) 318 | 319 | header_row = ["Check Title"] + platform_tags 320 | print(f"| {' | '.join(header_row)} |") 321 | print(f"| {' | '.join(['---' for i in range(platform_count + 1)])} |") 322 | 323 | for title in sorted(union): 324 | row = [] 325 | row.append(title) 326 | 327 | for platform_tag in platform_tags: 328 | if title in titles[platform_tag]: 329 | row.append("Yes") 330 | else: 331 | row.append("No") 332 | 333 | print(f"| {' | '.join(row)} |") 334 | 335 | sys.exit(0) 336 | 337 | 338 | 339 | 340 | 341 | 342 | --------------------------------------------------------------------------------