├── README.md └── poc-seeker.sh /README.md: -------------------------------------------------------------------------------- 1 | # POC Seeker 2 | 3 | POC Seeker is an innovative tool designed to streamline the process of finding and analyzing Proof of Concept (PoC) codes for known Common Vulnerabilities and Exposures (CVEs). 4 | 5 | ![POC Seeker](https://github.com/0xyassine/logo/blob/main/poc-seeker.png?raw=true) 6 | 7 | ## Features 8 | 9 | - **CVE Search**: Quickly search for CVEs to find associated PoC exploits. 10 | - **Database Integration**: Access a comprehensive database of CVEs with their detailed descriptions and associated PoCs. 11 | - **User-Friendly Interface**: Designed with ease of use in mind, POC Seeker can be used by professionals and beginners alike. 12 | - **Searching into 5 sources**: GitHub, Sploitus, Exploit-DB, Vulnerability-Lab, and Packet Storm Security, ensuring a comprehensive search with every query. 13 | - **Saving results to a file**: Search results can be saved to a file making it easy to reference and analyze data at a later time. 14 | - **Extension search**: Enhances search efficiency by directly targeting files that meet the specified criteria, reducing the volume of irrelevant data. 15 | 16 | ## Installation 17 | 18 | POC Seeker can be installed using one line 19 | 20 | ``` 21 | sudo curl -s https://raw.githubusercontent.com/0xyassine/poc-seeker/master/poc-seeker.sh -o /usr/local/bin/poc-seeker && sudo chmod +x /usr/local/bin/poc-seeker 22 | ``` 23 | 24 | ## Prerequisites 25 | 26 | POC Seeker script is written in Bash and relies on several (usually pre-installed) external packages to function correctly. Ensure that your system has the following packages installed before using the script: 27 | 28 | - **curl** 29 | - **Installation**: Most Linux distributions come with `curl` pre-installed. If you need to install it, you can typically do so using your package manager. For example, on Debian-based systems, use: 30 | ```bash 31 | sudo apt-get install curl 32 | ``` 33 | 34 | - **jq** 35 | - **Installation**: `jq` can be installed using your Linux distribution's package manager. For instance, on Debian-based systems, run: 36 | ```bash 37 | sudo apt-get install jq 38 | ``` 39 | 40 | - **searchsploit** 41 | - **Installation**: `searchsploit` is part of the Exploit Database repository. It can be installed on Debian-based systems by installing the `exploitdb` package or via a direct clone from its GitHub repository. For a direct installation, you can use: 42 | ```bash 43 | sudo git clone https://gitlab.com/exploit-database/exploitdb.git /opt/exploitdb 44 | sudo ln -sf /opt/exploitdb/searchsploit /usr/local/bin/searchsploit 45 | ``` 46 | Please refer to the [official Exploit-DB repository](https://github.com/offensive-security/exploitdb) for the most current installation instructions and options. 47 | 48 | 49 | ### Note: 50 | The script is designed to be as compatible as possible with various Linux distributions. However, due to the diversity of Linux environments and configurations, some commands or installation methods might need slight adjustments. Always refer to your distribution's documentation for the most accurate and up-to-date information regarding package management and software installation. 51 | 52 | 53 | ## Command Line Options 54 | 55 | POC Seeker supports a range of command-line options that enable users to customize their search for CVEs and associated PoCs. Below is a detailed explanation of each option: 56 | 57 | - `-h` | `--help` 58 | - **Description**: Displays a helpful menu that includes all command-line options along with a brief description of what they do. This option is useful for getting a quick overview of the tool's capabilities. 59 | - **Example**: `./poc-seeker.sh --help` 60 | 61 | - `-e` | `--extensions` 62 | - **Description**: Supply a list of file extensions separated by a comma and are optional; if not provided, the tool uses a default list. Make sure to select them correctly otherwise the script may not provide you non accurate results. 63 | - **Default Extensions**: .py,.rb,.pl,.sh,.ps1,.bat,.js,.php,.c,.cpp,.go,.lua,.rs,.swift 64 | - **Example**: `./poc-seeker.sh --query "CVE-2023-40028" -e ".sh,.py"` 65 | 66 | - `-q` | `--query` 67 | - **Description**: Allows the user to provide a search query, which is mandatory for performing a search. The query can be a specific CVE identifier, a keyword, or any other term related to the vulnerabilities you're interested in. 68 | - **Example**: `./poc-seeker.sh --query "CVE-2023-40028"` 69 | 70 | - `-s` | `--source` 71 | - **Description**: Enables specifying the sources from which to fetch the PoCs. The sources are separated by a comma and are optional; if not provided, the tool uses a default list of sources. 72 | - **Default Sources**: github, sploitus, exploit-db, vulnerability-lab, packetstormsecurity 73 | - **Example**: `./poc-seeker.sh --query "CVE-2023-40028" --source "github,exploit-db"` 74 | 75 | - `-c` | `--check` 76 | - **Description**: Activates a precise checking mechanism to ensure that the CVE identifier is explicitly mentioned in the exploit, thereby improving the accuracy of the search results. This option is optional but recommended for more accurate filtering. 77 | - **Example**: `./poc-seeker.sh --check --query "CVE-2023-40028"` 78 | 79 | - `-sl` | `--sploitus-limit` 80 | - **Description**: Sets a limit on the number of entries returned by Sploitus, allowing users to control the volume of data fetched. This is optional and can help in managing the output more effectively. 81 | - **Default Limit**: 10 82 | - **Example**: `./poc-seeker.sh --sploitus-limit 20 --query "CVE-2023-40028"` 83 | 84 | - `-gl` | `--github-limit` 85 | - **Description**: Sets a limit on the number of entries returned by GitHub, allowing users to control the volume of data fetched. This is optional and can help in managing the output more effectively. 86 | - **Default Limit**: 10 87 | - **Example**: `./poc-seeker.sh --github-limit 20 --query "CVE-2023-40028"` 88 | 89 | - `-o` | `--output` 90 | - **Description**: Saves the output of the search to a file. This option is beneficial for users who wish to review the results at a later time or keep a record of their searches. 91 | - **Example**: `./poc-seeker.sh --query "CVE-2023-40028" --output "search_results.txt"` 92 | 93 | - `--github-access-token` 94 | - **Description**: Accepts a GitHub access token to increase the API request limit, enabling more extensive data fetching operations without hitting the rate limits. This is optional but can be very useful for heavy users. 95 | - **Example**: `./poc-seeker.sh --query "CVE-2023-40028" --github-access-token "your_token_here"` 96 | 97 | - `--nvd-api-key` 98 | - **Description**: Provides an API key for the National Vulnerability Database (NVD) to increase the API request limit, similar to the GitHub access token. This option is optional and helps in conducting broader searches. 99 | - **Example**: `./poc-seeker.sh --query "CVE-2023-40028" --nvd-api-key "your_api_key_here"` 100 | 101 | - `--disable-nvd` 102 | - **Description**: By default, the script will try to collect CVE information from the National Vulnerability Database (NVD) database. You can use this option to prevent the script from collecting this informations. 103 | - **Example**: `./poc-seeker.sh --query "CVE-2023-40028" --disable-nvd` 104 | 105 | ## Disclaimer 106 | 107 | This repository and all associated files and resources are provided **for research purposes only**. The tools and information contained within this repository are intended to support security research and educational purposes. **This includes the use of web scraping technologies to gather data relevant to the research being conducted.** 108 | 109 | Users must comply with all applicable laws and regulations regarding web scraping and data collection. The owner and contributors of this repository do not accept any responsibility for misuse of the information provided here or for any legal consequences or damages arising from such use. 110 | -------------------------------------------------------------------------------- /poc-seeker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # By 0xyassine 4 | 5 | #COLORS 6 | NC='\033[0m' 7 | RED='\033[0;31m' 8 | GREEN='\033[0;32m' 9 | BLUE='\033[0;34m' 10 | CYAN='\033[1;36m' 11 | YELLOW='\033[1;33m' 12 | TOOL_VERSION=1.4 13 | 14 | ACCEPTED_SOURCES=(github sploitus exploit-db vulnerability-lab packetstormsecurity) 15 | 16 | function red 17 | { 18 | echo -ne "${RED}$1${NC}" 19 | } 20 | 21 | function green() 22 | { 23 | echo -ne "${GREEN}$1${NC}" 24 | } 25 | 26 | function blue() 27 | { 28 | echo -ne "${BLUE}$1${NC}" 29 | } 30 | 31 | function cyan() 32 | { 33 | echo -ne "${CYAN}$1${NC}" 34 | } 35 | 36 | function yellow() 37 | { 38 | echo -ne "${YELLOW}$1${NC}" 39 | } 40 | function white() 41 | { 42 | echo -ne "${NC}$1${NC}" 43 | } 44 | 45 | 46 | function logo() 47 | { 48 | echo 49 | echo "██████╗ ██████╗ ██████╗███████╗███████╗███████╗██╗ ██╗███████╗██████╗" 50 | echo "██╔══██╗██╔═══██╗██╔════╝██╔════╝██╔════╝██╔════╝██║ ██╔╝██╔════╝██╔══██╗" 51 | echo "██████╔╝██║ ██║██║ ███████╗█████╗ █████╗ █████╔╝ █████╗ ██████╔╝" 52 | echo "██╔═══╝ ██║ ██║██║ ╚════██║██╔══╝ ██╔══╝ ██╔═██╗ ██╔══╝ ██╔══██╗" 53 | echo "██║ ╚██████╔╝╚██████╗███████║███████╗███████╗██║ ██╗███████╗██║ ██║" 54 | echo "╚═╝ ╚═════╝ ╚═════╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝" 55 | echo 56 | printf " ${BLUE}Developer${NC}: 0xyassine\n" 57 | printf " ${BLUE}Version${NC} : ${RED}$TOOL_VERSION${NC}\n" 58 | printf " " 59 | echo 60 | } 61 | 62 | function help() 63 | { 64 | SCRIPT_NAME=$(basename "$0") 65 | echo "" 66 | green "OPTIONS:\n" 67 | printf "${CYAN} -h | --help${NC} Display this help menu 🤩\n" 68 | printf "${CYAN} -q | --query${NC} Provide search query (${RED}mandatory${NC}) 😀\n" 69 | printf "${CYAN} -s | --source${NC} Supply search source separated by a comma (optional) 🥸\n" 70 | printf " default : ${YELLOW}github,sploitus,exploit-db,vulnerability-lab${NC}\n" 71 | printf " available : ${CYAN}github,sploitus,exploit-db,vulnerability-lab,packetstormsecurity${NC}\n" 72 | printf "${CYAN} -e | --extensions${NC} Supply a list of file extensions separated by a comma used to search \n" 73 | printf " inside the respositories (optional)\n" 74 | printf " default : ${CYAN}.py,.rb,.pl,.sh,.ps1,.bat,.js,.php,.c,.cpp,.go,.lua,.rs,.swift${NC}\n" 75 | printf "${YELLOW} Be careful, do not use bash extension for windows based exploits 😉${NC}\n" 76 | printf "${CYAN} -c | --check${NC} The script accurately checks whether the CVE identifier is defined\n" 77 | printf " in the exploit to improve precision (optional) 🫠\n" 78 | printf "${CYAN} -sl | --sploitus-limit${NC} Limit the number of entries returned by sploitus (optional) 🙂\n" 79 | printf " default : ${CYAN}10${NC}\n" 80 | printf "${CYAN} -gl | --github-limit${NC} Limit the number of entries returned by github (optional) 🙂\n" 81 | printf " default : ${CYAN}10${NC}\n" 82 | printf "${CYAN} -o | --output${NC} Save the output to a file 🫣\n" 83 | printf "${CYAN} --github-access-token${NC} Supply a GitHub access token to increase the API request limit (optional) 😀\n" 84 | printf "${CYAN} --nvd-api-key${NC} Supply an NVD api key to increase the API request limit (optional) 😏\n" 85 | printf "${CYAN} --disable-nvd${NC} Prevent the script from searching for CVE details (optional) 😞\n" 86 | echo 87 | printf " E.g: ${RED}$(basename $0) -c -q CVE-2023-40028 -s github,sploitus -o cve-2023-40028.txt${NC}\n" 88 | echo 89 | } 90 | 91 | function spinner() 92 | { 93 | local CATEGORY="$2" 94 | local DESCRIPTION=$1 95 | local -a SPIN=("🤞" "👌" "🫰" "👍") 96 | local INTERVAL=0.1 97 | while :; do 98 | for CHAR in "${SPIN[@]}"; do 99 | printf "\r%s $DESCRIPTION ${RED}$CATEGORY${NC}" "$CHAR" 100 | sleep "$INTERVAL" 101 | done 102 | done 103 | } 104 | 105 | function install_packages() 106 | { 107 | echo 108 | local PACKAGE_NAME=$1 109 | if [ -f /etc/os-release ]; then 110 | . /etc/os-release 111 | OS=$ID_LIKE 112 | else 113 | printf "* ${CYAN}$PACKAGE_NAME${NC} is missing\n" 114 | return 1 115 | fi 116 | case $OS in 117 | ubuntu|debian|linuxmint) 118 | printf "* ${CYAN}$PACKAGE_NAME${NC} is missing, what about trying ${CYAN}sudo apt update && sudo apt install -y $PACKAGE_NAME ${NC}😀\n" 119 | ;; 120 | fedora|centos|rhel) 121 | if [[ "$OS" == "centos" || "$OS" == "rhel" ]]; then 122 | printf "* ${CYAN}$PACKAGE_NAME${NC} is missing, what about trying ${CYAN}sudo yum install -y $PACKAGE_NAME ${NC}😀\n" 123 | else 124 | printf "* ${CYAN}$PACKAGE_NAME${NC} is missing, what about trying ${CYAN}sudo dnf install -y $PACKAGE_NAME ${NC}😀\n" 125 | fi 126 | ;; 127 | arch|manjaro) 128 | printf "* ${CYAN}$PACKAGE_NAME${NC} is missing, what about trying ${CYAN}sudo pacman -Syu --noconfirm $PACKAGE_NAME ${NC}😀\n" 129 | ;; 130 | *) 131 | printf "* ${CYAN}$PACKAGE_NAME${NC} is missing\n" 132 | ;; 133 | esac 134 | } 135 | 136 | function verify_packages() 137 | { 138 | REQUIRED_PACKAGES=(curl jq) 139 | MISSING_PACKAGES=() 140 | for PACKAGE in ${REQUIRED_PACKAGES[@]};do 141 | if ! which $PACKAGE &>/dev/null;then 142 | MISSING_PACKAGES+=($PACKAGE) 143 | fi 144 | done 145 | if [ ${#MISSING_PACKAGES[@]} -ne 0 ];then 146 | red "😞 Please install the following packages before executing the script 😞\n" 147 | for MISSING in ${MISSING_PACKAGES[@]};do 148 | install_packages "$MISSING" 149 | done 150 | echo 151 | exit 1 152 | fi 153 | } 154 | 155 | function check_curl_features() 156 | { 157 | if ! curl --version | grep -q HTTP2;then 158 | yellow "🤔 I guess your curl version does not support HTTP/2. Sploitus search may fail 🤔\n" 159 | yellow "😎 However, you can install a new curl version to support this protocol 😎\n" 160 | echo 161 | fi 162 | } 163 | 164 | function check_for_update() 165 | { 166 | SCRIPT_RAW_URL="https://raw.githubusercontent.com/0xyassine/poc-seeker/master/poc-seeker.sh" 167 | REMOTE_VERSION=$(curl -r 0-160 -m 5 --connect-timeout 5 -s "$SCRIPT_RAW_URL" 2>/dev/null | grep 'TOOL_VERSION=' | awk -F= '{print $2}' | head -n 1) 168 | if [ $? -eq 0 ];then 169 | if [[ "$REMOTE_VERSION" == "$TOOL_VERSION" ]];then 170 | green "😎 The script is up-to-date 😎 \n" 171 | echo 172 | else 173 | yellow "You are using an outdated script version. The update is really easy using this command 🤓\n" 174 | cyan "sudo curl -s https://raw.githubusercontent.com/0xyassine/poc-seeker/master/poc-seeker.sh -o /usr/local/bin/poc-seeker && sudo chmod +x /usr/local/bin/poc-seeker\n" 175 | echo 176 | fi 177 | fi 178 | } 179 | 180 | #VARIABLES 181 | POTENTIAL_FINDING=() 182 | HAVE_A_LOOK=() 183 | CHECK_RESULTS=false 184 | HELP=false 185 | SEARCH_FIRST=false 186 | POC_SCRIPT_EXTENSIONS=( 187 | ".py" # Python, popular for its simplicity and the extensive availability of libraries 188 | ".rb" # Ruby, used for metaprogramming and quick exploits 189 | ".pl" # Perl, known for its text processing capabilities 190 | ".sh" # Shell script, for UNIX/Linux environments 191 | ".ps1" # PowerShell, powerful for Windows environments and automation 192 | ".bat" # Batch files, for simple Windows-oriented tasks 193 | ".js" # JavaScript, for web-based vulnerabilities and browser exploits 194 | ".php" # PHP, for server-side web application vulnerabilities 195 | ".c" # C language, for low-level exploits, buffer overflows, etc. 196 | ".cpp" # C++, used similarly to C for exploits requiring object-oriented features 197 | ".go" # Go, for writing efficient and concurrent programs, sometimes used in PoCs 198 | ".lua" # Lua, lightweight scripting language, used in game modding and sometimes web 199 | ".rs" # Rust, for safe and concurrent system-level exploits 200 | ".swift" # Swift, mainly for PoCs targeting Apple ecosystems 201 | # "nse" # nmap script 202 | ) 203 | 204 | #RANDOM USER AGENT 205 | USER_AGENTS=( 206 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3" 207 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15" 208 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36" 209 | "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:85.0) Gecko/20100101 Firefox/85.0" 210 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0" 211 | ) 212 | RANDOM_UA=${USER_AGENTS[$RANDOM % ${#USER_AGENTS[@]}]} 213 | 214 | function exploit-db() 215 | { 216 | if ! which searchsploit &> /dev/null;then 217 | printf "😔${CYAN} You have to install${NC} ${RED}searchsploit${NC} ${CYAN}to search into exploit-db${NC} 😔\n" 218 | if [ -f /etc/os-release ]; then 219 | . /etc/os-release 220 | OS=$ID 221 | if [[ "$OS" == "kali" ]];then 222 | printf " Seems like you are using Kali linux, what about trying ${CYAN}sudo apt update && sudo apt install -y exploitdb ${NC}😀\n" 223 | else 224 | printf "You can check ${CYAN}https://gitlab.com/exploit-database/exploitdb${NC} 😀\n" 225 | fi 226 | else 227 | printf "You can check ${CYAN}https://gitlab.com/exploit-database/exploitdb${NC} 😀\n" 228 | fi 229 | else 230 | spinner "Searching" "exploit db" & 231 | if [[ ! -z "$CVE_FROM_QUERY" ]];then 232 | RESULTS=$(searchsploit --cve "$CVE_FROM_QUERY" -w | awk '{print $NF}' | grep 'http') 233 | else 234 | RESULTS=$(searchsploit "$QUERY" -w | awk '{print $NF}' | grep 'http') 235 | fi 236 | for URL in $RESULTS;do 237 | FILE_ID=$(echo "$URL" | awk -F/ '{print $NF}') 238 | if $CHECK_RESULTS && [[ ! -z "$CVE_FROM_QUERY" ]];then 239 | if searchsploit -p $FILE_ID | grep -wq "$CVE_FROM_QUERY";then 240 | POTENTIAL_FINDING+=("$URL") 241 | else 242 | HAVE_A_LOOK+=("$URL") 243 | fi 244 | else 245 | POTENTIAL_FINDING+=("$URL") 246 | fi 247 | done 248 | kill "$!" 249 | printf "\r🤞 Searching ${RED}exploit db${NC} ${GREEN} DONE${NC}\n" 250 | fi 251 | } 252 | 253 | #GET ALL GITHUB REPOS FOUND BY THE SEARCH QUERY 254 | function github_repos() 255 | { 256 | local QUERY="$@" 257 | if [ ! -z $GITHUB_TOKEN ];then 258 | QUERY_RESULT=$(curl -m 15 --connect-timeout 15 -s -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github+json" "https://api.github.com/search/repositories?q=${QUERY}+in:name,description&sort=stars&order=desc" 2>/dev/null) 259 | REPOS=$( echo "$QUERY_RESULT" | jq -r '.items[] | .full_name' 2>/dev/null | head -n $GITHUB_LIMIT) 260 | else 261 | QUERY_RESULT=$(curl -m 15 --connect-timeout 15 -s -H "Accept: application/vnd.github+json" "https://api.github.com/search/repositories?q=${QUERY}+in:name,description&sort=stars&order=desc" 2>/dev/null) 262 | REPOS=$(echo "$QUERY_RESULT" | jq -r '.items[] | .full_name' 2>/dev/null | head -n $GITHUB_LIMIT) 263 | fi 264 | if [ $? -eq 0 ];then 265 | REPOS=$(echo $REPOS | tr '\n' ' ') 266 | else 267 | if echo "$QUERY_RESULT" | jq -r .message | grep -qi 'API rate limit';then 268 | GITHUB_SEARCH_FAILED=true 269 | IS_RATE_LIMITED=true 270 | GITHUB_EXTENSIONS_FAILED=true 271 | else 272 | GITHUB_SEARCH_FAILED=true 273 | fi 274 | fi 275 | } 276 | 277 | #GET FILES INSIDE THE GITHUB REPO 278 | function github_repo_files() 279 | { 280 | local REPO="$@" 281 | sleep 0.1 282 | if [ ! -z $GITHUB_TOKEN ];then 283 | CONTENT_RESULTS=$(curl -m 15 --connect-timeout 15 -s -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github+json" "https://api.github.com/repos/$REPO/contents" 2>/dev/null) 284 | FILE_LIST=$( echo "$CONTENT_RESULTS" | jq -r '.[] | .name' 2>/dev/null) 285 | else 286 | CONTENT_RESULTS=$(curl -m 15 --connect-timeout 15 -s -H "Accept: application/vnd.github+json" "https://api.github.com/repos/$REPO/contents" 2>/dev/null) 287 | FILE_LIST=$(echo "$CONTENT_RESULTS" | jq -r '.[] | .name' 2>/dev/null) 288 | fi 289 | if [ $? -eq 0 ];then 290 | FILE_LIST=$(echo $FILE_LIST | tr '\n' ' ') 291 | else 292 | if echo "$CONTENT_RESULTS" | jq -r .message | grep -qi 'API rate limit';then 293 | IS_RATE_LIMITED=true 294 | GITHUB_EXTENSIONS_FAILED=true 295 | else 296 | GITHUB_EXTENSIONS_FAILED=true 297 | fi 298 | fi 299 | } 300 | 301 | function github() 302 | { 303 | GITHUB_SEARCH_FAILED=false 304 | GITHUB_EXTENSIONS_FAILED=false 305 | IS_RATE_LIMITED=false 306 | 307 | spinner "Searching" "github" & 308 | #GET THE LIST OF REPOSITORIES 309 | github_repos "$QUERY" 310 | for REPO in $REPOS; do 311 | sleep 0.5 312 | #GET THE LIST OF FILES INSIDE THE REPOSITORY 313 | if ! $IS_RATE_LIMITED && ! $GITHUB_EXTENSIONS_FAILED;then 314 | github_repo_files "$REPO" 315 | else 316 | if $GITHUB_SEARCH_FAILED;then 317 | echo 318 | red "\n 🤯 Searching github repositories failed. Results from GitHub may not be accurate 🤯 \n" 319 | echo 320 | fi 321 | if $GITHUB_EXTENSIONS_FAILED;then 322 | echo 323 | red "\n 🤯 Searching github for file extensions failed. Results from GitHub may not be accurate 🤯 \n" 324 | echo 325 | fi 326 | if $IS_RATE_LIMITED;then 327 | echo 328 | red "\n 🤯 GitHub Api rate limit is hit. Results from GitHub may not be accurate 🤯 \n" 329 | echo 330 | fi 331 | if [ -z $GITHUB_TOKEN ];then 332 | printf " * Consider using ${CYAN}--github-access-token${NC} option 😀\n" 333 | fi 334 | kill "$!" 335 | return 336 | fi 337 | POTENTIAL=false 338 | POSSIBLE=false 339 | REPO_WITH_README=false 340 | REQUIRED_EXTENSION_FOUND=false 341 | CVE_FOUND=false 342 | if echo "$FILE_LIST" | grep -qEi 'README\.md';then 343 | REPO_WITH_README=true 344 | fi 345 | #CHECK FILE EXTENSION 346 | if echo "$FILE_LIST" | grep -Eqi "($(echo ${POC_SCRIPT_EXTENSIONS[@]} | tr ' ' '|' | sed -e 's/\./\\./g' | sed 's/|/\ \|/g' | sed -e 's/$/\ /'))";then 347 | REQUIRED_EXTENSION_FOUND=true 348 | fi 349 | #FINDING 350 | if $REPO_WITH_README;then 351 | if curl -m 15 --connect-timeout 15 -s "https://raw.githubusercontent.com/$REPO/main/README.md" | grep -wiq "$CVE_FROM_QUERY";then 352 | CVE_FOUND=true 353 | elif curl -m 15 --connect-timeout 15 -s "https://raw.githubusercontent.com/$REPO/master/README.md" | grep -wiq "$CVE_FROM_QUERY";then 354 | CVE_FOUND=true 355 | fi 356 | if $REQUIRED_EXTENSION_FOUND && $CVE_FOUND;then 357 | POTENTIAL=true 358 | else 359 | ! $CHECK_RESULTS && POSSIBLE=true 360 | fi 361 | else 362 | if $REQUIRED_EXTENSION_FOUND;then 363 | POTENTIAL=true 364 | else 365 | ! $CHECK_RESULTS && POSSIBLE=true 366 | fi 367 | fi 368 | if $POTENTIAL;then 369 | POTENTIAL_FINDING+=("https://github.com/$REPO ") 370 | fi 371 | if $POSSIBLE;then 372 | HAVE_A_LOOK+=("https://github.com/$REPO ") 373 | fi 374 | done 375 | kill "$!" 376 | if ! $GITHUB_SEARCH_FAILED;then 377 | printf "\r🤞 Searching ${RED}github${NC} ${GREEN} DONE${NC}\n" 378 | fi 379 | } 380 | 381 | function sploitus() 382 | { 383 | SPLOITUS_SEARCH_FAILED=false 384 | spinner "Searching" "sploitus" & 385 | OFFSET=0 386 | MAX_ITEMS=$SPLOITUS_LIMIT 387 | while true;do 388 | ALL_INFO=$(curl -m 15 --connect-timeout 15 -s -X $'POST' -H $'Host: sploitus.com' -H "Accept: application/json" -H "Content-Type: application/json" -H "User-Agent: $RANDOM_UA" -H $'Origin: https://sploitus.com' -H "Referer: https://sploitus.com/?query=${QUERY}" -H $'Accept-Language: en-US,en;q=0.9' --data "{\"type\":\"exploits\",\"sort\":\"default\",\"query\":\"${QUERY}\",\"title\":false,\"offset\":${OFFSET}}" https://sploitus.com/search 2>/dev/null | jq) 389 | if [ $? -ne 0 ];then 390 | echo 391 | red "🤯 Searching sploitus failed 🤯 \n" 392 | SPLOITUS_SEARCH_FAILED=true 393 | break 394 | echo 395 | fi 396 | if $CHECK_RESULTS && [[ ! -z "$CVE_FROM_QUERY" ]];then 397 | URLS=$(echo $ALL_INFO | jq -r --arg KEY "$CVE_FROM_QUERY" '.exploits[] | select(.source | test($KEY; "i")) | .href' 2>/dev/null | tr '\n' ' ') 398 | else 399 | URLS=$(echo "$ALL_INFO" | jq -r '.exploits[] | .href' 2>/dev/null | tr '\n' ' ') 400 | fi 401 | if [ $(echo "$URLS" | wc -l) -eq 0 ];then 402 | break 403 | fi 404 | for URL in "$URLS";do 405 | HAVE_A_LOOK+=($URL) 406 | done 407 | OFFSET=$((OFFSET + 10)) 408 | if [ $OFFSET -eq $MAX_ITEMS ];then 409 | break 410 | fi 411 | done 412 | kill "$!" 413 | if ! $SPLOITUS_SEARCH_FAILED;then 414 | printf "\r🤞 Searching ${RED}sploitus${NC} ${GREEN} DONE${NC}\n" 415 | fi 416 | } 417 | 418 | function packetstormsecurity() 419 | { 420 | PACKETSTORM_SEARCH_FAILED=false 421 | spinner "Searching" "packetstormsecurity" & 422 | PACKET_STORM_IDS=$(curl -m 5 --connect-timeout 5 -s "https://packetstormsecurity.com/search/?q=${QUERY}&s=files" -H "User-Agent: $RANDOM_UA" 2>/dev/null | grep -Eo '\/files\/[0-9]*\/' | awk -F/ '{print $3}' | sort -u) 423 | if [ $? -eq 0 ];then 424 | for FILE_ID in $(echo $PACKET_STORM_IDS);do 425 | sleep 1 426 | if $CHECK_RESULTS && [[ ! -z "$CVE_FROM_QUERY" ]];then 427 | if curl -m 5 --connect-timeout 5 -s "https://packetstormsecurity.com/files/${FILE_ID}" -H "User-Agent: $RANDOM_UA" 2>/dev/null | grep -wiq "$CVE_FROM_QUERY";then 428 | HAVE_A_LOOK+=("https://packetstormsecurity.com/files/${FILE_ID}/") 429 | fi 430 | else 431 | HAVE_A_LOOK+=("https://packetstormsecurity.com/files/${FILE_ID}/") 432 | fi 433 | done 434 | else 435 | red "🤯 Searching packetstorm security failed 🤯 \n" 436 | PACKETSTORM_SEARCH_FAILED=true 437 | fi 438 | kill "$!" 439 | if ! $PACKETSTORM_SEARCH_FAILED;then 440 | printf "\r🤞 Searching ${RED}packetstormsecurity${NC} ${GREEN} DONE${NC}\n" 441 | fi 442 | } 443 | 444 | function vulnerability-lab() 445 | { 446 | VULNERABILITY_LAB_SEARCH_FAILED=false 447 | spinner "Searching" "vulnerability lab" & 448 | VULNERABILITY_LIST=$(curl -m 15 --connect-timeout 15 -i -s -k -X GET -H $'Host: www.vulnerability-lab.com' -H $'Upgrade-Insecure-Requests: 1' -H "User-Agent: $RANDOM_UA" -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' -H $'Referer: https://www.vulnerability-lab.com/search.php' "https://www.vulnerability-lab.com/search.php?search=${QUERY}&submit=Search" 2>/dev/null | grep -Eo 'get\_content\.php\?id=[0-9]*' | sort -u) 449 | if [ $? -eq 0 ];then 450 | for ID_URL in $(echo $VULNERABILITY_LIST);do 451 | sleep 1 452 | if $CHECK_RESULTS && [[ ! -z "$CVE_FROM_QUERY" ]];then 453 | if curl -m 15 --connect-timeout 15 -s "https://www.vulnerability-lab.com/$ID_URL" 2>/dev/null | grep -wiq "$CVE_FROM_QUERY";then 454 | POTENTIAL_FINDING+=("https://www.vulnerability-lab.com/$ID_URL") 455 | fi 456 | else 457 | HAVE_A_LOOK+=("https://www.vulnerability-lab.com/$ID_URL") 458 | fi 459 | done 460 | else 461 | red "🤯 Searching vulnerability lab failed 🤯 \n" 462 | VULNERABILITY_LAB_SEARCH_FAILED=true 463 | fi 464 | kill "$!" 465 | if ! $VULNERABILITY_LAB_SEARCH_FAILED;then 466 | printf "\r🤞 Searching ${RED}vulnerability lab${NC} ${GREEN} DONE${NC}\n" 467 | fi 468 | } 469 | 470 | function print_item() 471 | { 472 | local LABLE=$1 473 | local VALUE=$2 474 | printf "${RED}-> ${NC}${BLUE}%-20s${NC}: %s\n" "$LABLE" "$VALUE" 475 | if [ ! -z "$OUTPUT_FILE" ] && ! $IGNORE_SAVING_OUTPUT;then 476 | printf "%-20s: %s\n" "$LABLE" "$VALUE" >> $OUTPUT_FILE 477 | fi 478 | } 479 | 480 | NVD_DISABLED=false 481 | function nvd_collect_information() 482 | { 483 | cyan "🤓 Hold on, trying to collect few details 🤓\n" 484 | CVE_FROM_QUERY=$(echo "$CVE_FROM_QUERY" | tr 'a-z' 'A-Z') 485 | if [[ ! -z "$NVD_API_KEY" ]];then 486 | ALL_DETAILS=$(curl -m 15 --connect-timeout 15 -s --location "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=$CVE_FROM_QUERY" -H "apiKey: $NVD_API_KEY") 487 | else 488 | ALL_DETAILS=$(curl -m 15 --connect-timeout 15 -s --location "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=$CVE_FROM_QUERY") 489 | fi 490 | TOTAL_RESULTS=$(echo $ALL_DETAILS | jq -r '.totalResults') 491 | if [[ ! -z "$ALL_DETAILS" ]] && [[ $TOTAL_RESULTS -ne 0 ]];then 492 | SEARCH_FIRST=true 493 | cyan "🥳 Before searching for a valid POC, I've got few details for you 🥳\n" 494 | echo 495 | printf '%.0s-' {1..30} 496 | echo 497 | CVE_ID=$(echo "$ALL_DETAILS" | jq -r '.vulnerabilities[0].cve.id') 498 | CVE_DESCRIPTION=$(echo "$ALL_DETAILS" | jq -r '.vulnerabilities[0].cve.descriptions[0].value') 499 | BASE_SCORE=$(echo "$ALL_DETAILS" | jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.baseScore') 500 | ATTACK_COMPLEXITY=$(echo "$ALL_DETAILS" | jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.attackComplexity') 501 | USER_INTERACTION=$(echo "$ALL_DETAILS" | jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.userInteraction') 502 | PRIVILEGES_REQUIRED=$(echo "$ALL_DETAILS" | jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.privilegesRequired') 503 | if [[ ! -z "$CVE_ID" ]]; then 504 | print_item "CVE id" "$CVE_ID" 505 | fi 506 | if [[ ! -z "$CVE_DESCRIPTION" ]]; then 507 | print_item "CVE description" "$CVE_DESCRIPTION" 508 | fi 509 | if [[ ! -z "$BASE_SCORE" ]]; then 510 | print_item "Base score" "$BASE_SCORE" 511 | fi 512 | if [[ ! -z "$ATTACK_COMPLEXITY" ]]; then 513 | print_item "Attack complexity" "$ATTACK_COMPLEXITY" 514 | fi 515 | if [[ ! -z "$USER_INTERACTION" ]]; then 516 | print_item "User interaction" "$USER_INTERACTION" 517 | fi 518 | if [[ ! -z "$PRIVILEGES_REQUIRED" ]]; then 519 | print_item "Required privileges" "$PRIVILEGES_REQUIRED" 520 | fi 521 | printf '%.0s-' {1..30} 522 | echo;echo 523 | fi 524 | } 525 | 526 | logo 527 | verify_packages 528 | check_curl_features 529 | 530 | #IS THE TOOL EXECUTED WITHOUT ANY ARGUEMTNS? 531 | if [[ $# -eq 0 ]];then 532 | red "🤯 Looks like you executed the script without any arguments 🤯 \n" 533 | green "🤓 No worries, I can help 🤓\n" 534 | help 535 | exit 1 536 | fi 537 | 538 | while [[ $# -gt 0 ]]; do 539 | case "$1" in 540 | -q|--query) 541 | if [ -n "$2" ]; then 542 | QUERY="$2" 543 | QUERY=$(echo "$QUERY" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') 544 | shift 2 545 | else 546 | red "😔 Opsss ! Search query not provided after -q or --query 😔\n" 547 | exit 1 548 | fi 549 | ;; 550 | -o|--output) 551 | if [ -n "$2" ]; then 552 | OUTPUT_FILE="$2" 553 | shift 2 554 | else 555 | red "😔 Opsss ! Output file name not provided after -o or --output 😔\n" 556 | help 557 | exit 1 558 | fi 559 | ;; 560 | --nvd-api-key) 561 | if [ -n "$2" ]; then 562 | NVD_API_KEY="$2" 563 | shift 2 564 | else 565 | red "😔 Opsss ! Nvd api key not provided after --nvd-api-key 😔\n" 566 | exit 1 567 | fi 568 | ;; 569 | -c|--check) 570 | CHECK_RESULTS=true 571 | shift 572 | ;; 573 | --disable-nvd) 574 | NVD_DISABLED=true 575 | shift 576 | ;; 577 | -h|--help) 578 | HELP=true 579 | shift 580 | ;; 581 | --github-access-token) 582 | if [ -n "$2" ]; then 583 | GITHUB_TOKEN="$2" 584 | shift 2 585 | else 586 | red "😔 Opsss ! Github token not provided after the --github-access-token option 😔\n" 587 | exit 1 588 | fi 589 | ;; 590 | -s|--source) 591 | if [ -n "$2" ]; then 592 | SOURCE_LIST="$2" 593 | SOURCE_LIST=$(echo "$SOURCE_LIST" | tr ',' ' ') 594 | for SOURCE in $SOURCE_LIST;do 595 | if ! echo ${ACCEPTED_SOURCES[@]} | grep -qwF "$SOURCE";then 596 | red "😔 Opsss ! you provided a non valid source [ $SOURCE ] 😔\n" 597 | help 598 | exit 1 599 | fi 600 | done 601 | shift 2 602 | else 603 | red "😔 Opsss ! The source is not provided after the -s or --source option 😔\n" 604 | exit 1 605 | fi 606 | ;; 607 | -e|--extensions) 608 | if [ -n "$2" ]; then 609 | EXTENSIONS_LIST="$2" 610 | EXTENSIONS_LIST=($(echo "$EXTENSIONS_LIST" | tr ',' ' ')) 611 | for EXTENSIONS in ${EXTENSIONS_LIST[@]};do 612 | if ! [[ $EXTENSIONS =~ ^\.[a-zA-Z0-9]+$ ]];then 613 | red "😔 [ $EXTENSIONS ] does not have a valid file extension format 😔\n" 614 | echo 615 | help 616 | exit 617 | fi 618 | done 619 | shift 2 620 | else 621 | red "😔 Opsss ! The extensions are not provided after the -e or --extensions option 😔\n" 622 | exit 1 623 | fi 624 | ;; 625 | -sl|--sploitus-limit) 626 | if [ -n "$2" ]; then 627 | SPLOITUS_LIMIT="$2" 628 | if ! ([[ $SPLOITUS_LIMIT =~ ^[0-9]+$ ]] && [ $(($SPLOITUS_LIMIT % 10)) -eq 0 ]);then 629 | red "😔 Opsss ! Sploitus search limit can only be a number multiple of 10 😔\n" 630 | help 631 | exit 1 632 | fi 633 | shift 2 634 | else 635 | red "😔 Opsss ! Sploitus search limit is not provided after the -sl or --sploitus-limit option 😔\n" 636 | exit 1 637 | fi 638 | ;; 639 | -gl|--github-limit) 640 | if [ -n "$2" ]; then 641 | GITHUB_LIMIT="$2" 642 | if ! [[ $GITHUB_LIMIT =~ ^[0-9]+$ ]];then 643 | red "😔 Opsss ! GitHub search limit can only be a number 😔\n" 644 | help 645 | exit 1 646 | fi 647 | shift 2 648 | else 649 | red "😔 Opsss ! GitHub search limit is not provided after the -gl or --github-limit option 😔\n" 650 | exit 1 651 | fi 652 | ;; 653 | *) 654 | red "😱 Oh noo, you provided unknown argument [ $1 ] 😱\n" 655 | green "Maybe it's time to have a look at the help menu again 😉\n" 656 | help 657 | exit 1 658 | ;; 659 | esac 660 | done 661 | 662 | if $HELP;then 663 | help 664 | exit 665 | fi 666 | 667 | #MAKE SURE WE HAVE AN INPUT 668 | if [ -z "$QUERY" ];then 669 | red "🥶 Unfortunately I can't search for CVE if you don't provide an input 🥶\n" 670 | printf "🙄 ${BLUE}Please use${NC} ${CYAN}-q ${NC} or ${CYAN}--query ${NC}${BLUE}option${NC}🙄\n" 671 | help 672 | exit 1 673 | else 674 | if [ $(echo "$QUERY" | wc -c) -le 2 ];then 675 | yellow "😕 You used a very short query, please don't blame me if I found nothing useful 😕\n" 676 | echo 677 | fi 678 | CVE=$(echo "$QUERY" | grep -oiE 'CVE-[0-9]*-[0-9]*') 679 | if [[ ! -z "$CVE" ]];then 680 | if [ $(echo $CVE | awk -F- '{print $2}' | wc -c) -lt 5 ] || [ $(echo $CVE | awk -F- '{print $3}' | wc -c) -lt 5 ];then 681 | yellow "😕 Seems like the CVE id is not really correct, results may not be accurate 😕\n" 682 | echo 683 | fi 684 | fi 685 | fi 686 | 687 | echo 688 | check_for_update 689 | 690 | if [ -z "$SPLOITUS_LIMIT" ] || [ $SPLOITUS_LIMIT -lt 10 ];then 691 | SPLOITUS_LIMIT=10 692 | fi 693 | if [ -z "$GITHUB_LIMIT" ];then 694 | GITHUB_LIMIT=10 695 | fi 696 | 697 | #EXTRACT THE CVE FROM THE QUERY 698 | CVE_FROM_QUERY=$(echo "$QUERY" | grep -oiE 'CVE-[0-9]{4}-[0-9]{4,}') 699 | if [ ! -z "$CVE_FROM_QUERY" ];then 700 | if [ $(echo "$CVE_FROM_QUERY" | tr ' ' '\n' | wc -l) -gt 1 ];then 701 | red "😪 Searching for multiple CVE's is not supported for now 😪\n" 702 | cyan "😉 This will be implemented in the future 😉\n" 703 | exit 1 704 | fi 705 | fi 706 | 707 | IGNORE_SAVING_OUTPUT=false 708 | if [ ! -z "$OUTPUT_FILE" ];then 709 | if [ ! -f $OUTPUT_FILE ];then 710 | if ! mkdir -p $(dirname $OUTPUT_FILE) &>/dev/null;then 711 | red "😔 I failed to create the output directory for you, maybe check you permissions 😔\n" 712 | echo 713 | IGNORE_SAVING_OUTPUT=true 714 | else 715 | if ! touch $OUTPUT_FILE &>/dev/null;then 716 | red "😔 I failed to create the output file for you, maybe check you permissions 😔\n" 717 | echo 718 | IGNORE_SAVING_OUTPUT=true 719 | fi 720 | fi 721 | else 722 | if ! touch $OUTPUT_FILE &>/dev/null;then 723 | red "😔 I failed to write to the output file for you, maybe check you permissions 😔\n" 724 | echo 725 | IGNORE_SAVING_OUTPUT=true 726 | fi 727 | fi 728 | fi 729 | 730 | if [ ! -z "$OUTPUT_FILE" ] && ! $IGNORE_SAVING_OUTPUT;then 731 | echo "------------" > $OUTPUT_FILE 732 | echo "$QUERY" >> $OUTPUT_FILE 733 | echo "------------" >> $OUTPUT_FILE 734 | fi 735 | 736 | if [[ ! -z "$CVE_FROM_QUERY" ]] && ! $NVD_DISABLED;then 737 | nvd_collect_information 738 | fi 739 | 740 | if ! $SEARCH_FIRST;then 741 | printf "🥸 ${BLUE}I am searching for${NC}${CYAN} $QUERY ${NC}${BLUE}POC, hold on ${NC} 🥸\n" 742 | echo 743 | fi 744 | 745 | if [[ ! -z "$EXTENSIONS_LIST" ]];then 746 | POC_SCRIPT_EXTENSIONS=(${EXTENSIONS_LIST[@]}) 747 | fi 748 | 749 | if [[ -z "$SOURCE_LIST" ]];then 750 | github 751 | sploitus 752 | exploit-db 753 | vulnerability-lab 754 | else 755 | for SOURCE in $SOURCE_LIST;do 756 | $SOURCE 757 | done 758 | fi 759 | 760 | 761 | echo 762 | if [ ${#POTENTIAL_FINDING[@]} -ne 0 ];then 763 | green "😎 I think I've found potential POC for you 😎 \n" 764 | echo 765 | if [ ! -z "$OUTPUT_FILE" ] && ! $IGNORE_SAVING_OUTPUT;then 766 | echo '' >> $OUTPUT_FILE 767 | echo "Potential POC's" >> $OUTPUT_FILE 768 | fi 769 | for POTENTIAL in $(echo ${POTENTIAL_FINDING[@]} | tr ' ' '\n' | sort -u);do 770 | printf "\r${RED}[+] ${NC}${GREEN}${POTENTIAL} ${NC}\n" 771 | if [ ! -z "$OUTPUT_FILE" ] && ! $IGNORE_SAVING_OUTPUT;then 772 | echo "[+] $POTENTIAL" >> $OUTPUT_FILE 773 | fi 774 | done 775 | echo 776 | fi 777 | 778 | 779 | for ITEM in ${POTENTIAL_FINDING[@]};do 780 | if echo ${HAVE_A_LOOK[@]} | grep -q "$ITEM";then 781 | HAVE_A_LOOK=($(echo ${HAVE_A_LOOK[@]} | sed -e "s#$ITEM##g")) 782 | fi 783 | done 784 | 785 | 786 | 787 | if [ ${#HAVE_A_LOOK[@]} -ne 0 ];then 788 | green "🧐 You may have a look at the following 🧐 \n" 789 | echo 790 | if [ ! -z "$OUTPUT_FILE" ] && ! $IGNORE_SAVING_OUTPUT;then 791 | echo '' >> $OUTPUT_FILE 792 | echo "Have a look" >> $OUTPUT_FILE 793 | fi 794 | for POSSIBLE in $(echo ${HAVE_A_LOOK[@]} | tr ' ' '\n' | sort -u);do 795 | printf "\r${RED}[!] ${NC}${YELLOW}$POSSIBLE${NC}\n" 796 | if [ ! -z "$OUTPUT_FILE" ] && ! $IGNORE_SAVING_OUTPUT;then 797 | echo "[!] $POSSIBLE" >> $OUTPUT_FILE 798 | fi 799 | done 800 | fi 801 | 802 | if [ ${#HAVE_A_LOOK[@]} -eq 0 ] && [ ${#POTENTIAL_FINDING[@]} -eq 0 ];then 803 | red "🥺 Oh no I wasn't able to find any POC for you 🥺 \n" 804 | fi 805 | 806 | if [ ! -z "$OUTPUT_FILE" ] && ! $IGNORE_SAVING_OUTPUT;then 807 | echo "------------" >> $OUTPUT_FILE 808 | echo "------------" >> $OUTPUT_FILE 809 | fi 810 | --------------------------------------------------------------------------------