Repository: detexploit/DetExploit Branch: master Commit: 042d6633ca93 Files: 27 Total size: 73.2 KB Directory structure: gitextract_vecmjc2k/ ├── .gitignore ├── INIReader/ │ ├── INIReader.cpp │ ├── INIReader.h │ ├── ini.c │ └── ini.h ├── README.md ├── README_JAPANESE.md ├── addon.cpp ├── autoupd.cpp ├── compile.sh ├── config.ini ├── detexploit.hpp ├── dev_config.ini ├── exploitdb.cpp ├── jvn.cpp ├── local_app.cpp ├── main.cpp ├── nvd.cpp ├── report.cpp ├── resources/ │ ├── default.ini │ ├── langpack/ │ │ ├── en_langdata.hpp │ │ └── ja_langdata.hpp │ ├── report_template.html │ ├── report_template.md │ └── report_template.txt ├── utils.cpp └── winupdate.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.log *.pyc *.vbs detexploit_report* history.detexploit exploitdb.detexploit ================================================ FILE: INIReader/INIReader.cpp ================================================ // Read an INI file into easy-to-access name/value pairs. // SPDX-License-Identifier: BSD-3-Clause // Copyright (C) 2009-2019, Ben Hoyt // inih and INIReader are released under the New BSD license (see LICENSE.txt). // Go to the project home page for more info: // // https://github.com/benhoyt/inih #include #include #include #include "ini.h" #include "INIReader.h" using std::string; INIReader::INIReader(const string& filename) { _error = ini_parse(filename.c_str(), ValueHandler, this); } int INIReader::ParseError() const { return _error; } string INIReader::Get(const string& section, const string& name, const string& default_value) const { string key = MakeKey(section, name); // Use _values.find() here instead of _values.at() to support pre C++11 compilers return _values.count(key) ? _values.find(key)->second : default_value; } string INIReader::GetString(const string& section, const string& name, const string& default_value) const { const string str = Get(section, name, ""); return str.empty() ? default_value : str; } long INIReader::GetInteger(const string& section, const string& name, long default_value) const { string valstr = Get(section, name, ""); const char* value = valstr.c_str(); char* end; // This parses "1234" (decimal) and also "0x4D2" (hex) long n = strtol(value, &end, 0); return end > value ? n : default_value; } double INIReader::GetReal(const string& section, const string& name, double default_value) const { string valstr = Get(section, name, ""); const char* value = valstr.c_str(); char* end; double n = strtod(value, &end); return end > value ? n : default_value; } bool INIReader::GetBoolean(const string& section, const string& name, bool default_value) const { string valstr = Get(section, name, ""); // Convert to lower case to make string comparisons case-insensitive std::transform(valstr.begin(), valstr.end(), valstr.begin(), ::tolower); if (valstr == "true" || valstr == "yes" || valstr == "on" || valstr == "1") return true; else if (valstr == "false" || valstr == "no" || valstr == "off" || valstr == "0") return false; else return default_value; } bool INIReader::HasSection(const string& section) const { const string key = MakeKey(section, ""); std::map::const_iterator pos = _values.lower_bound(key); if (pos == _values.end()) return false; // Does the key at the lower_bound pos start with "section"? return pos->first.compare(0, key.length(), key) == 0; } bool INIReader::HasValue(const string& section, const string& name) const { string key = MakeKey(section, name); return _values.count(key); } string INIReader::MakeKey(const string& section, const string& name) { string key = section + "=" + name; // Convert to lower case to make section/name lookups case-insensitive std::transform(key.begin(), key.end(), key.begin(), ::tolower); return key; } int INIReader::ValueHandler(void* user, const char* section, const char* name, const char* value) { INIReader* reader = static_cast(user); string key = MakeKey(section, name); if (reader->_values[key].size() > 0) reader->_values[key] += "\n"; reader->_values[key] += value; return 1; } ================================================ FILE: INIReader/INIReader.h ================================================ // Read an INI file into easy-to-access name/value pairs. // SPDX-License-Identifier: BSD-3-Clause // Copyright (C) 2009-2019, Ben Hoyt // inih and INIReader are released under the New BSD license (see LICENSE.txt). // Go to the project home page for more info: // // https://github.com/benhoyt/inih #ifndef __INIREADER_H__ #define __INIREADER_H__ #include #include // Read an INI file into easy-to-access name/value pairs. (Note that I've gone // for simplicity here rather than speed, but it should be pretty decent.) class INIReader { public: // Construct INIReader and parse given filename. See ini.h for more info // about the parsing. explicit INIReader(const std::string& filename); // Return the result of ini_parse(), i.e., 0 on success, line number of // first error on parse error, or -1 on file open error. int ParseError() const; // Get a string value from INI file, returning default_value if not found. std::string Get(const std::string& section, const std::string& name, const std::string& default_value) const; // Get a string value from INI file, returning default_value if not found, // empty, or contains only whitespace. std::string GetString(const std::string& section, const std::string& name, const std::string& default_value) const; // Get an integer (long) value from INI file, returning default_value if // not found or not a valid integer (decimal "1234", "-1234", or hex "0x4d2"). long GetInteger(const std::string& section, const std::string& name, long default_value) const; // Get a real (floating point double) value from INI file, returning // default_value if not found or not a valid floating point value // according to strtod(). double GetReal(const std::string& section, const std::string& name, double default_value) const; // Get a boolean value from INI file, returning default_value if not found or if // not a valid true/false value. Valid true values are "true", "yes", "on", "1", // and valid false values are "false", "no", "off", "0" (not case sensitive). bool GetBoolean(const std::string& section, const std::string& name, bool default_value) const; // Return true if the given section exists (section must contain at least // one name=value pair). bool HasSection(const std::string& section) const; // Return true if a value exists with the given section and field names. bool HasValue(const std::string& section, const std::string& name) const; private: int _error; std::map _values; static std::string MakeKey(const std::string& section, const std::string& name); static int ValueHandler(void* user, const char* section, const char* name, const char* value); }; #endif // __INIREADER_H__ ================================================ FILE: INIReader/ini.c ================================================ /* inih -- simple .INI file parser SPDX-License-Identifier: BSD-3-Clause Copyright (C) 2009-2019, Ben Hoyt inih is released under the New BSD license (see LICENSE.txt). Go to the project home page for more info: https://github.com/benhoyt/inih */ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS #endif #include #include #include #include "ini.h" #if !INI_USE_STACK #include #endif #define MAX_SECTION 50 #define MAX_NAME 50 /* Used by ini_parse_string() to keep track of string parsing state. */ typedef struct { const char* ptr; size_t num_left; } ini_parse_string_ctx; /* Strip whitespace chars off end of given string, in place. Return s. */ static char* rstrip(char* s) { char* p = s + strlen(s); while (p > s && isspace((unsigned char)(*--p))) *p = '\0'; return s; } /* Return pointer to first non-whitespace char in given string. */ static char* lskip(const char* s) { while (*s && isspace((unsigned char)(*s))) s++; return (char*)s; } /* Return pointer to first char (of chars) or inline comment in given string, or pointer to null at end of string if neither found. Inline comment must be prefixed by a whitespace character to register as a comment. */ static char* find_chars_or_comment(const char* s, const char* chars) { #if INI_ALLOW_INLINE_COMMENTS int was_space = 0; while (*s && (!chars || !strchr(chars, *s)) && !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) { was_space = isspace((unsigned char)(*s)); s++; } #else while (*s && (!chars || !strchr(chars, *s))) { s++; } #endif return (char*)s; } /* Version of strncpy that ensures dest (size bytes) is null-terminated. */ static char* strncpy0(char* dest, const char* src, size_t size) { strncpy(dest, src, size - 1); dest[size - 1] = '\0'; return dest; } /* See documentation in header file. */ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, void* user) { /* Uses a fair bit of stack (use heap instead if you need to) */ #if INI_USE_STACK char line[INI_MAX_LINE]; int max_line = INI_MAX_LINE; #else char* line; int max_line = INI_INITIAL_ALLOC; #endif #if INI_ALLOW_REALLOC && !INI_USE_STACK char* new_line; int offset; #endif char section[MAX_SECTION] = ""; char prev_name[MAX_NAME] = ""; char* start; char* end; char* name; char* value; int lineno = 0; int error = 0; #if !INI_USE_STACK line = (char*)malloc(INI_INITIAL_ALLOC); if (!line) { return -2; } #endif #if INI_HANDLER_LINENO #define HANDLER(u, s, n, v) handler(u, s, n, v, lineno) #else #define HANDLER(u, s, n, v) handler(u, s, n, v) #endif /* Scan through stream line by line */ while (reader(line, max_line, stream) != NULL) { #if INI_ALLOW_REALLOC && !INI_USE_STACK offset = strlen(line); while (offset == max_line - 1 && line[offset - 1] != '\n') { max_line *= 2; if (max_line > INI_MAX_LINE) max_line = INI_MAX_LINE; new_line = realloc(line, max_line); if (!new_line) { free(line); return -2; } line = new_line; if (reader(line + offset, max_line - offset, stream) == NULL) break; if (max_line >= INI_MAX_LINE) break; offset += strlen(line + offset); } #endif lineno++; start = line; #if INI_ALLOW_BOM if (lineno == 1 && (unsigned char)start[0] == 0xEF && (unsigned char)start[1] == 0xBB && (unsigned char)start[2] == 0xBF) { start += 3; } #endif start = lskip(rstrip(start)); if (strchr(INI_START_COMMENT_PREFIXES, *start)) { /* Start-of-line comment */ } #if INI_ALLOW_MULTILINE else if (*prev_name && *start && start > line) { /* Non-blank line with leading whitespace, treat as continuation of previous name's value (as per Python configparser). */ if (!HANDLER(user, section, prev_name, start) && !error) error = lineno; } #endif else if (*start == '[') { /* A "[section]" line */ end = find_chars_or_comment(start + 1, "]"); if (*end == ']') { *end = '\0'; strncpy0(section, start + 1, sizeof(section)); *prev_name = '\0'; #if INI_CALL_HANDLER_ON_NEW_SECTION if (!HANDLER(user, section, NULL, NULL) && !error) error = lineno; #endif } else if (!error) { /* No ']' found on section line */ error = lineno; } } else if (*start) { /* Not a comment, must be a name[=:]value pair */ end = find_chars_or_comment(start, "=:"); if (*end == '=' || *end == ':') { *end = '\0'; name = rstrip(start); value = end + 1; #if INI_ALLOW_INLINE_COMMENTS end = find_chars_or_comment(value, NULL); if (*end) *end = '\0'; #endif value = lskip(value); rstrip(value); /* Valid name[=:]value pair found, call handler */ strncpy0(prev_name, name, sizeof(prev_name)); if (!HANDLER(user, section, name, value) && !error) error = lineno; } else if (!error) { /* No '=' or ':' found on name[=:]value line */ error = lineno; } } #if INI_STOP_ON_FIRST_ERROR if (error) break; #endif } #if !INI_USE_STACK free(line); #endif return error; } /* See documentation in header file. */ int ini_parse_file(FILE* file, ini_handler handler, void* user) { return ini_parse_stream((ini_reader)fgets, file, handler, user); } /* See documentation in header file. */ int ini_parse(const char* filename, ini_handler handler, void* user) { FILE* file; int error; file = fopen(filename, "r"); if (!file) return -1; error = ini_parse_file(file, handler, user); fclose(file); return error; } /* An ini_reader function to read the next line from a string buffer. This is the fgets() equivalent used by ini_parse_string(). */ static char* ini_reader_string(char* str, int num, void* stream) { ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream; const char* ctx_ptr = ctx->ptr; size_t ctx_num_left = ctx->num_left; char* strp = str; char c; if (ctx_num_left == 0 || num < 2) return NULL; while (num > 1 && ctx_num_left != 0) { c = *ctx_ptr++; ctx_num_left--; *strp++ = c; if (c == '\n') break; num--; } *strp = '\0'; ctx->ptr = ctx_ptr; ctx->num_left = ctx_num_left; return str; } /* See documentation in header file. */ int ini_parse_string(const char* string, ini_handler handler, void* user) { ini_parse_string_ctx ctx; ctx.ptr = string; ctx.num_left = strlen(string); return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler, user); } ================================================ FILE: INIReader/ini.h ================================================ /* inih -- simple .INI file parser SPDX-License-Identifier: BSD-3-Clause Copyright (C) 2009-2019, Ben Hoyt inih is released under the New BSD license (see LICENSE.txt). Go to the project home page for more info: https://github.com/benhoyt/inih */ #ifndef __INI_H__ #define __INI_H__ /* Make this header file easier to include in C++ code */ #ifdef __cplusplus extern "C" { #endif #include /* Nonzero if ini_handler callback should accept lineno parameter. */ #ifndef INI_HANDLER_LINENO #define INI_HANDLER_LINENO 0 #endif /* Typedef for prototype of handler function. */ #if INI_HANDLER_LINENO typedef int (*ini_handler)(void* user, const char* section, const char* name, const char* value, int lineno); #else typedef int (*ini_handler)(void* user, const char* section, const char* name, const char* value); #endif /* Typedef for prototype of fgets-style reader function. */ typedef char* (*ini_reader)(char* str, int num, void* stream); /* Parse given INI-style file. May have [section]s, name=value pairs (whitespace stripped), and comments starting with ';' (semicolon). Section is "" if name=value pair parsed before any section heading. name:value pairs are also supported as a concession to Python's configparser. For each name=value pair parsed, call handler function with given user pointer as well as section, name, and value (data only valid for duration of handler call). Handler should return nonzero on success, zero on error. Returns 0 on success, line number of first error on parse error (doesn't stop on first error), -1 on file open error, or -2 on memory allocation error (only when INI_USE_STACK is zero). */ int ini_parse(const char* filename, ini_handler handler, void* user); /* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't close the file when it's finished -- the caller must do that. */ int ini_parse_file(FILE* file, ini_handler handler, void* user); /* Same as ini_parse(), but takes an ini_reader function pointer instead of filename. Used for implementing custom or string-based I/O (see also ini_parse_string). */ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, void* user); /* Same as ini_parse(), but takes a zero-terminated string with the INI data instead of a file. Useful for parsing INI data from a network socket or already in memory. */ int ini_parse_string(const char* string, ini_handler handler, void* user); /* Nonzero to allow multi-line value parsing, in the style of Python's configparser. If allowed, ini_parse() will call the handler with the same name for each subsequent line parsed. */ #ifndef INI_ALLOW_MULTILINE #define INI_ALLOW_MULTILINE 1 #endif /* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of the file. See https://github.com/benhoyt/inih/issues/21 */ #ifndef INI_ALLOW_BOM #define INI_ALLOW_BOM 1 #endif /* Chars that begin a start-of-line comment. Per Python configparser, allow both ; and # comments at the start of a line by default. */ #ifndef INI_START_COMMENT_PREFIXES #define INI_START_COMMENT_PREFIXES ";#" #endif /* Nonzero to allow inline comments (with valid inline comment characters specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match Python 3.2+ configparser behaviour. */ #ifndef INI_ALLOW_INLINE_COMMENTS #define INI_ALLOW_INLINE_COMMENTS 1 #endif #ifndef INI_INLINE_COMMENT_PREFIXES #define INI_INLINE_COMMENT_PREFIXES ";" #endif /* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */ #ifndef INI_USE_STACK #define INI_USE_STACK 1 #endif /* Maximum line length for any line in INI file (stack or heap). Note that this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */ #ifndef INI_MAX_LINE #define INI_MAX_LINE 200 #endif /* Nonzero to allow heap line buffer to grow via realloc(), zero for a fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is zero. */ #ifndef INI_ALLOW_REALLOC #define INI_ALLOW_REALLOC 0 #endif /* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK is zero. */ #ifndef INI_INITIAL_ALLOC #define INI_INITIAL_ALLOC 200 #endif /* Stop parsing on first error (default is to keep parsing). */ #ifndef INI_STOP_ON_FIRST_ERROR #define INI_STOP_ON_FIRST_ERROR 0 #endif /* Nonzero to call the handler at the start of each new section (with name and value NULL). Default is to only call the handler on each name=value pair. */ #ifndef INI_CALL_HANDLER_ON_NEW_SECTION #define INI_CALL_HANDLER_ON_NEW_SECTION 0 #endif #ifdef __cplusplus } #endif #endif /* __INI_H__ */ ================================================ FILE: README.md ================================================ **This README is English version.** **If you want to view Japanese version, please check the [README_JAPANESE.md](README_JAPANESE.md).** [![GitHub Release](https://img.shields.io/github/release/detexploit/DetExploit.svg)](https://github.com/detexploit/DetExploit/releases/latest) [![License: GPLv2](https://img.shields.io/badge/license-GPL--3.0-blue)](www.gnu.org/licenses/gpl-3.0.en.html) ## Info (Last Update: 2019/10/04) Hi, thank you for visiting this repository. You may know that there is no commit for a while...... but development is still going on !!! Currently, I am re-writing whole program into C++ to reduce binary size and more advantages. This is very important procedure to release our program, so please understand it... :) I've prepared some milestone, so you may check out it!! ``` Schedule 1. Python to C++ to resuce binary size 2. Release binary from GitHub Releases 3. Publish demo movies of client/server (Currently working on ...) 4. Publish slides of DetExploit (Japanese version is already ready, so wait for little bit more!!) ``` ## Table of contents - [DetExploit v1.3α](#detexploit-v13α) - [Table of contents](#table-of-contents) - [Abstract](#abstract) - [Demo](#demo) - [How to run](#how-to-run) - [Supported Database](#supported-database) - [License](#license) - [Contact to developer](#contact-to-developer) ## Abstract DetExploit is software that detect vulnerable applications and not-installed important OS updates on the system, and notify them to user. As we know, most of cyberattacks uses vulnerability that is released out year before. I thought this is huge problem, and this kind of technology should be more powerful than technology that will detect unknown malwares or exploits. Also this project is my theme of [Mitou Jr](https://jr.mitou.org/index_en.html) project in Japan. I wish and work hard to make this an huge OSS (Open Source Software) project, to help these days society. ## Demo + Demo Video Clip (v0.5, English, Click and jump to YouTube to play video) [![Alt text](https://img.youtube.com/vi/VBev9dtGtEM/0.jpg)](https://www.youtube.com/watch?v=VBev9dtGtEM) ## How to run **You can download latest stable build of DetExploit from [Releases](https://github.com/detexploit/DetExploit/releases) page.** Easiest way to run is shown below (Do not forget to unzip the downloaded file). ``` # Execute DetExploit C:\path\to>cd DetExploit_ReleaseYYYYMMDD C:\path\to\DetExlopit_ReleaseYYYYMMDD>DetExploit.exe ``` ## Supported Database + [ExploitDB](https://exploit-db.com/) + [JVN (Japan Vulnerability Notes)](https://jvn.jp/) + [NVD (National Vulnerability Database)](https://nvd.nist.gov/) + [US-CERT](https://www.us-cert.gov/) + [JPCERT](https://www.jpcert.or.jp/) + More on further version ## License GNU GPLv3 License ## Contact to developer + MOPI (Email: [moppoi5168@gmail.com](mailto:moppoi5168@gmail.com) / Twitter: [@moppoi5168](https://twitter.com/moppoi5168)) ================================================ FILE: README_JAPANESE.md ================================================ # DetExploit v1.3α ![ScreenShot1](resources/sshot_v0.9-alpha.png) ** DetExploit v0.9αのスクリーンショット ** [English Version README is right here (英語版のREADMEを表示)](README.md) ## 目次 - [DetExploit v1.3α](#detexploit-v13α) - [目次](#目次) - [概要](#概要) - [デモ](#デモ) - [実行方法](#実行方法) - [サポートしているデータベース](#サポートしているデータベース) - [ライセンス](#ライセンス) - [開発者へ連絡](#開発者へ連絡) ## 概要 DetExploitはシステム上に存在する脆弱なアプリケーションやインストールされていない重要なOSのアップデートを検知して、ユーザーに通知するソフトウェアです。 近年のサイバー攻撃で使用されるほとんどの脆弱性が一年以上前に攻撃コードなどが公開されているものだというのは皆さんご存知だと思います。 そんな状況ならば未知の脅威に対処するための技術よりも既知の脅威に対処するための技術が発展するべきだと私は考えました。 本プロジェクトは私の[未踏ジュニア](https://jr.mitou.org/)のテーマ作品です。 私は本プロジェクトが発展して、大規模なOSSになることを願い開発を続けていきます。 ## デモ + デモ映像 (v0.5, クリックするとYouTubeにジャンプします) [![Alt text](https://img.youtube.com/vi/aIMhaA_ysUY/0.jpg)](https://www.youtube.com/watch?v=aIMhaA_ysUY) ## 実行方法 **[Releases](https://github.com/detexploit/DetExploit/releases) から最新のビルドをダウンロードすることができます。** 最も簡単な方法を以下に記しておきます (ダウンロードしたzip圧縮ファイルを解凍することを忘れないでくださいね!!) ``` # DetExploitを実行 C:\path\to>cd DetExploit_ReleaseYYYYMMDD C:\path\to\DetExlopit_ReleaseYYYYMMDD>DetExploit.exe ``` ## サポートしているデータベース + [ExploitDB](https://exploit-db.com/) + [JVN (Japan Vulnerability Notes)](https://jvn.jp/) + [NVD (National Vulnerability Database)](https://nvd.nist.gov/) + [US-CERT](https://www.us-cert.gov/) + [JPCERT](https://www.jpcert.or.jp/) + 随時追加予定 ## ライセンス GNU GPLv3 License ## 開発者へ連絡 + MOPI (Email: [moppoi5168@gmail.com](mailto:moppoi5168@gmail.com) / Twitter: [@naogramer](https://twitter.com/moppoi5168)) ================================================ FILE: addon.cpp ================================================ /* addon.cpp DetExploit program file for loading external function file (addon). DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #define DEXP_ADDON_SIGN "SignStartDetExploitAddonPackage1.2SignEnd" #include "detexploit.hpp" std::vector load_addon(const std::string& src, const char* delim) { std::vector vec; std::string::size_type len = src.length(); for (std::string::size_type i = 0, n; i < len; i = n + 1) { n = src.find_first_of(delim, i); if (n == std::string::npos) { n = len; } vec.push_back(src.substr(i, n - i)); } return vec; } std::string insert_inst(const std::vector& v, const char* delim) { std::string s = ""; if (!v.empty()) { s += v[0]; for (decltype(v.size()) i = 1, c = v.size(); i < c; ++i) { if (delim) s += delim; s += v[i]; } } return s; } ================================================ FILE: autoupd.cpp ================================================ /* addon.cpp DetExploit program file for loading external function file (addon). DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #define DEXP_ADDON_SIGN "SignStartDetExploitAddonPackage1.2SignEnd" #include "detexploit.hpp" std::vector load_addon(const std::string& src, const char* delim) { std::vector vec; std::string::size_type len = src.length(); for (std::string::size_type i = 0, n; i < len; i = n + 1) { n = src.find_first_of(delim, i); if (n == std::string::npos) { n = len; } vec.push_back(src.substr(i, n - i)); } return vec; } std::string insert_inst(const std::vector& v, const char* delim) { std::string s = ""; if (!v.empty()) { s += v[0]; for (decltype(v.size()) i = 1, c = v.size(); i < c; ++i) { if (delim) s += delim; s += v[i]; } } return s; } ================================================ FILE: compile.sh ================================================ i686-w64-mingw32-g++ -c main.cpp -o main.detexploit -I./include i686-w64-mingw32-g++ -c exploitdb.cpp -o exploitdb.detexploit -I./include i686-w64-mingw32-g++ -c jvn.cpp -o jvn.detexploit -I./include i686-w64-mingw32-g++ -c nvd.cpp -o nvd.detexploit -I./include i686-w64-mingw32-g++ -c winupdate.cpp -o winupdate.detexploit -I./include i686-w64-mingw32-g++ -c utils.cpp -o utils.detexploit -I./include i686-w64-mingw32-g++ -c report.cpp -o report.detexploit -I./include i686-w64-mingw32-g++ -c local_app.cpp -o local_app.detexploit -I./include i686-w64-mingw32-g++ -c INIReader/INIReader.cpp -o INIReader.detexploit -I./include i686-w64-mingw32-gcc -c INIReader/ini.c -o ini.detexploit -I./include i686-w64-mingw32-g++ -std=c++11 main.detexploit exploitdb.detexploit jvn.detexploit nvd.detexploit winupdate.detexploit utils.detexploit report.detexploit local_app.detexploit INIReader.detexploit ini.detexploit -o DetExploit.exe -s -lws2_32 -lurlmon -lwininet -Wno-write-strings -I./include -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc rm *.detexploit ================================================ FILE: config.ini ================================================ ########################################################### # dev_config.ini # Configuration file of DetExploit. # DetExploit (https://github.com/moppoi5168/DetExploit) # Licensed by GPL License ########################################################### [general] # DetExploit Language Settings (Default Value: en) lang = en # DetExploit will automaticly delete vulnerability data if you set True here. (Default Value: True) do_not_save_vulndata = True # If you want to scan also for the operating system update, set True here. (Default Value: True) os_update_scan = True # The scan report format of DetExploit. (Default Value: HTML) report_format = HTML [exploitdb] # If you want to use ExploitDB as source of vulnerability data, set True here. (Default Value: True) use_exploitdb = True # File name that DetExploit saves ExploitDB vulnerability data. (Default Value: exploitdb.detexploit) vulndata_filename = exploitdb.detexploit [jvn] # If you want to use JVN as source of vulnerability data, set True here. (Default Value: True) use_jvn = True # The time range of vulnerability data from JVN. # If you make it longer, time that is required to process will also be longer. (Default Value: 2010, 2019) data_from = 2010 data_to = 2019 [nvd] # If you want to use JVN as source of vulnerability data, set True here. (Default Value: True) use_nvd = True # The time range of vulnerability data from NVD. # If you make it longer, time that is required to process will also be longer. (Default Value: 2010, 2019) data_from = 2010 data_to = 2019 [server] # Name to be identified by DetExploit Server id = NONAME # Host Address for the DetExploit Server host = 0.0.0.0 # Port to serve DetExploit Server (HTTP) port = 4321 # Interval time while client checks scan cmd interval = 10 # Debug Mode debug = True ================================================ FILE: detexploit.hpp ================================================ /* detexploit.hpp Header file of DetExploit C++ Program. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #ifndef DETEXPLOIT_HPP #define DETEXPLOIT_HPP #define DETEXPLOIT_VERSION "v1.4-ALPHA-CLI" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "urlmon.lib") #pragma comment(lib, "wininet.lib") //#include #include "resources/langpack/en_langdata.hpp" #include "INIReader/INIReader.h" typedef struct DVI { std::string version; bool is_edb; bool is_jvn; bool is_nvd; bool is_winupd; std::string severity; } VulnInfo; /* main.cpp */ INIReader init_cp(char *arg); /* exploitdb.cpp */ #define EDB_VULNDATA_FILENAME "exploitdb.detexploit" std::map proc_edb(HANDLE hStdout); int edb_download_vulndata(HANDLE hStdout); std::vector edb_extract_vulndata(HANDLE hStdout); std::map edb_parse_vulndata(std::vector data_list); std::map edb_scan(std::map edb_vulndata, std::map installed); /* jvn.cpp */ std::map jvn_download_vulndata(HANDLE hStdout); std::map jvn_scan(std::map jvn_vulndata, std::map installed); /* nvd.cpp */ std::map nvd_download_vulndata(HANDLE hStdout); std::map nvd_scan(std::map nvd_vulndata, std::map installed); /* winupdate.cpp */ /* utils.cpp */ std::string ghostname(); bool checkFileExistence(const std::string& str); std::vector split(const std::string& src, const char* delim); std::string join(const std::vector& v, const char* delim); std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len); bool config_test(); /* report.cpp */ std::string determine_severity(std::string data_src, std::string ext); void generate_report(INIReader cp, std::string session_id, std::string scan_starttime, std::string scan_endtime, std::map resultdict); /* local_app.cpp */ std::map getapp_all(); std::map getapp_from_wmi(); std::map getapp_from_hklm(); std::map getapp_from_hklmwow64(); std::map getapp_from_hkcu(); #endif ================================================ FILE: dev_config.ini ================================================ ########################################################### # dev_config.ini # Configuration file of DetExploit. # DetExploit (https://github.com/moppoi5168/DetExploit) # Licensed by GPL License ########################################################### [general] # DetExploit Language Settings (Default Value: en) lang = ja # DetExploit will automaticly delete vulnerability data if you set True here. (Default Value: True) do_not_save_vulndata = True # If you want to scan also for the operating system update, set True here. (Default Value: True) os_update_scan = True # The scan report format of DetExploit. (Default Value: HTML) report_format = HTML [exploitdb] # If you want to use ExploitDB as source of vulnerability data, set True here. (Default Value: True) use_exploitdb = True # File name that DetExploit saves ExploitDB vulnerability data. (Default Value: exploitdb.detexploit) vulndata_filename = exploitdb.detexploit [jvn] # If you want to use JVN as source of vulnerability data, set True here. (Default Value: True) use_jvn = True # The time range of vulnerability data from JVN. # If you make it longer, time that is required to process will also be longer. (Default Value: 2010, 2019) data_from = 2019 data_to = 2019 [nvd] # If you want to use JVN as source of vulnerability data, set True here. (Default Value: True) use_nvd = True # The time range of vulnerability data from NVD. # If you make it longer, time that is required to process will also be longer. (Default Value: 2010, 2019) data_from = 2019 data_to = 2019 [server] # Name to be identified by DetExploit Server id = NONAME # Host Address for the DetExploit Server host = 0.0.0.0 # Port to serve DetExploit Server (HTTP) port = 4321 # Interval time while client checks scan cmd interval = 10 # Debug Mode debug = True ================================================ FILE: exploitdb.cpp ================================================ /* exploitdb.cpp DetExploit program file related to ExploitDB. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #include "detexploit.hpp" std::map proc_edb(HANDLE hStdout) { std::vector extracted; std::map edb_vulndata; edb_download_vulndata(hStdout); extracted = edb_extract_vulndata(hStdout); edb_vulndata = edb_parse_vulndata(extracted); return edb_vulndata; } int edb_download_vulndata(HANDLE hStdout) { LPCTSTR Url, File; HRESULT hr; std::cout << EXPLOITDB_DOWNLOAD_INTRO << std::endl; std::string edb_url = ""; std::string savepath = EDB_VULNDATA_FILENAME; Url = _T("https://github.com/offensive-security/exploitdb/raw/master/files_exploits.csv"); File = _T(EDB_VULNDATA_FILENAME); hr = URLDownloadToFile(0, Url, File, 0, 0); if (checkFileExistence(EDB_VULNDATA_FILENAME)) { SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN); std::cout << EXPLOITDB_DOWNLOAD_SUCCESS << std::endl; SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); std::cout << "===========================================================" << std::endl; } else { SetConsoleTextAttribute(hStdout, FOREGROUND_RED); std::cout << EXPLOITDB_DOWNLOAD_FAILED << std::endl; SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); exit(1); } } std::vector edb_extract_vulndata(HANDLE hStdout) { std::vector tmp; std::string str; std::ifstream ifs(EDB_VULNDATA_FILENAME); std::string extract_msg = EXPLOITDB_EXTRACT_WIN; extract_msg += EDB_VULNDATA_FILENAME; extract_msg += "......"; std::cout << extract_msg << std::endl; while (getline(ifs, str)) { if (str.find("windows") != std::string::npos) { tmp.push_back(str.c_str()); } } SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN); std::cout << EXPLOITDB_EXTRACT_SUCCESS << std::endl; SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); std::cout << "===========================================================" << std::endl; return tmp; } std::map edb_parse_vulndata(std::vector data_list) { std::map product_dict; for (int i = 0; i < data_list.size(); i++) { std::vector splitted = split(data_list[i], ","); std::string base = splitted[2]; std::vector splitted_sec = split(base, " "); std::string name = splitted_sec[0] + splitted_sec[1]; std::string version = splitted_sec[2]; product_dict[name] = version; } return product_dict; } std::map edb_scan(std::map edb_vulndata, std::map installed) { std::map resultdict; std::string level = ""; VulnInfo vinfo; for (auto fit = edb_vulndata.begin(); fit != edb_vulndata.end(); fit++) { for (auto nit = installed.begin(); nit != installed.end(); nit++) { if ((*fit).first == (*nit).first && (*fit).second == (*nit).second) { level = determine_severity(EDB, "NOEXT"); vinfo.version = (*fit).second; vinfo.is_edb = true; vinfo.is_jvn = false; vinfo.is_nvd = false; vinfo.is_winupd = false; vinfo.severity = level; resultdict[(*fit).first] = vinfo; std::cout << "===========================================================" << std::endl; std::cout << DETECT_ALERT << std::endl; std::cout << APP_NAME << (*fit).first << " >>" << std::endl; std::cout << APP_VERSION << (*fit).second << " >>" << std::endl; std::cout << DETECT_USING_NVD << std::endl; std::cout << OBJECT_LEVEL << level << " >>" << std::endl; std::cout << "===========================================================" << std::endl; } } } return resultdict; } ================================================ FILE: jvn.cpp ================================================ /* jvn.cpp DetExploit program file related to JVN. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #include "detexploit.hpp" std::map jvn_download_vulndata(HANDLE hStdout) { std::map product_dict; std::string Url = ""; std::string str = ""; std::cout << JVN_DOWNLOAD_INTRO << std::endl; std::cout << JVN_DOWNLOAD_ALERT_ONE << std::endl; std::cout << JVN_DOWNLOAD_ALERT_TWO << "\n\n"; for (int y = 2019; y < 2020; y++) { // int y = 2010 for (int m = 1; m < 13; m++) { Url = "https://jvndb.jvn.jp/myjvn?method=getVulnOverviewList&feed=hnd&rangeDatePublished=n&rangeDateFirstPublished=n&datePublicStartY="; Url += std::to_string(y); Url += "&datePublicStartM="; Url += std::to_string(m); Url += "&datePublicEmdY="; Url += std::to_string(y); Url += "&datePublicEmdM="; Url += std::to_string(m); URLDownloadToFile(0, Url.c_str(), _T("jvn_temp.xml"), 0, 0); std::ifstream ifs("jvn_temp.xml"); while (getline(ifs, str)) { if (str.find("sec:cpe") != std::string::npos) { std::vector splitted = split(str.substr(6), " "); try { std::string name = splitted[3].substr(9); std::string va = splitted[1].substr(9); std::string version = va.erase(va.size() - 1); product_dict[name] = version; } catch (...) { continue; } } } } std::cout << JVN_DOWNLOAD_PROGRESS << std::to_string(y) << std::endl; } SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN); std::cout << JVN_DOWNLOAD_SUCCESS << std::endl; SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); std::cout << "===========================================================" << std::endl; return product_dict; } std::map jvn_scan(std::map jvn_vulndata, std::map installed) { std::map resultdict; std::string level = ""; VulnInfo vinfo; for (auto fit = jvn_vulndata.begin(); fit != jvn_vulndata.end(); fit++) { for (auto nit = installed.begin(); nit != installed.end(); nit++) { if ((*fit).first == (*nit).first && (*fit).second == (*nit).second) { level = determine_severity(JVN, "NOEXT"); vinfo.version = (*fit).second; vinfo.is_edb = true; vinfo.is_jvn = false; vinfo.is_nvd = false; vinfo.is_winupd = false; vinfo.severity = level; resultdict[(*fit).first] = vinfo; std::cout << "===========================================================" << std::endl; std::cout << DETECT_ALERT << std::endl; std::cout << APP_NAME << (*fit).first << " >>" << std::endl; std::cout << APP_VERSION << (*fit).second << " >>" << std::endl; std::cout << DETECT_USING_JVN << std::endl; std::cout << OBJECT_LEVEL << level << " >>" << std::endl; std::cout << "===========================================================" << std::endl; } } } return resultdict; } ================================================ FILE: local_app.cpp ================================================ /* local_app.cpp DetExploit program file related to local application info. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #include "detexploit.hpp" std::map getapp_all() { std::map data; std::map wmi_data = getapp_from_wmi(); std::map hklm_data = getapp_from_hklm(); std::map hklmwow64_data = getapp_from_hklmwow64(); std::map hkcu_data = getapp_from_hkcu(); data.insert(wmi_data.begin(), wmi_data.end()); data.insert(wmi_data.begin(), hklm_data.end()); data.insert(wmi_data.begin(), hklmwow64_data.end()); data.insert(wmi_data.begin(), hkcu_data.end()); return data; } std::map getapp_from_wmi() { std::map data; std::system("powershell.exe Get-WmiObject -class Win32_Product > WMIRET.detexploit"); // ファイルを開いて中身をstd::stringに流し込む // NameとVersionだけ上手く取り出して、mapに入れる if (!(DeleteFileA("WMIRET.detexploit"))) { std::cout << "Warning: Failed to delete HKLMRET.detexploit" << std::endl; } return data; } std::map getapp_from_hklm() { std::map data; // reg query "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall" /s | findstr "DisplayName DisplayVersion" // DisplayNameより先にDisplayVersionが表示されることがある // DisplayNameが来る前にDisplayVersionが来たらそれを次DisplayNameが来るまで保持する感じで std::system("powershell.exe Get-WmiObject -class Win32_Product > HKLMRET.detexploit"); // ファイルを開いて中身をstd::stringに流し込む // for文を回して上に書いていた機構を実装する if (!(DeleteFileA("HKLMRET.detexploit"))) { std::cout << "Warning: Failed to delete HKLMRET.detexploit" << std::endl; } return data; } std::map getapp_from_hklmwow64() { std::map data; return data; } std::map getapp_from_hkcu() { std::map data; return data; } ================================================ FILE: main.cpp ================================================ /* main.cpp Main C++ program file of DetExploit. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #include "detexploit.hpp" int main(int argc, char *argv[]) { INIReader cp = init_cp(argv[1]); std::cout << cp.Get("jvn", "data_from", "0000") << std::endl; int count = 0; char scan_starttime[128] = ""; char scan_endtime[128] = ""; HANDLE hStdout; CONSOLE_SCREEN_BUFFER_INFO csbi; hStdout = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hStdout, &csbi); SetConsoleTextAttribute(hStdout, FOREGROUND_RED); std::cout << R"( ____ _ _____ _ _ _ | _ \ ___| |_| ____|_ ___ __ | | ___ (_) |_ | | | |/ _ \ __| _| \ \/ / '_ \| |/ _ \| | __| | |_| | __/ |_| |___ > <| |_) | | (_) | | |_ |____/ \___|\__|_____/_/\_\ .__/|_|\___/|_|\__| |_| )" << std::endl; SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); std::cout << "===========================================================" << std::endl; std::cout << WELCOME_MESSAGE << std::endl; std::cout << "===========================================================" << std::endl; time_t start = time(NULL); struct tm *pstart = localtime(&start); sprintf(scan_starttime, "%d/%d/%d %d:%d:%d", pstart->tm_year+1900, pstart->tm_mon+1, pstart->tm_mday, pstart->tm_hour, pstart->tm_min, pstart->tm_sec); std::string stime_str = std::string(scan_starttime); std::string session_id = base64_encode(reinterpret_cast(stime_str.c_str()), stime_str.length()); std::map edb_vulndata = proc_edb(hStdout); std::map jvn_vulndata = jvn_download_vulndata(hStdout); std::map nvd_vulndata = nvd_download_vulndata(hStdout); std::map installed = getapp_all(); std::map result; std::map scanret_exploitdb = edb_scan(edb_vulndata, installed); std::map scanret_jvn = jvn_scan(jvn_vulndata, installed); std::map scanret_nvd = nvd_scan(nvd_vulndata, installed); // std::map scanret_winupdate = windowsupdate_scan(); result.insert(scanret_exploitdb.begin(), scanret_exploitdb.end()); result.insert(scanret_jvn.begin(), scanret_jvn.end()); result.insert(scanret_nvd.begin(), scanret_nvd.end()); // result.insert(scanret_winupdate.begin(), scanret_winupdate.end()); time_t end = time(NULL); struct tm *pend = localtime(&end); sprintf(scan_endtime, "%d/%d/%d %d:%d:%d", pend->tm_year+1900, pend->tm_mon+1, pend->tm_mday, pend->tm_hour, pend->tm_min, pend->tm_sec); std::string history = "\n"; history += "Session ID: " + session_id; history += "\n"; history += "Scan started at: " + std::string(scan_starttime); history += "\n"; history += "Scan ended at: " + std::string(scan_endtime); history += "\n"; history += "Found vulnerable application and available update: " + std::to_string(count); history += "\n"; history += "DetExploit Version: "; history += DETEXPLOIT_VERSION; history += "\n\n#####################################################################\n\n"; std::ofstream writeFile; writeFile.open("history.detexploit"); writeFile << history; generate_report(cp, session_id, std::string(scan_starttime), std::string(scan_endtime), result); SetConsoleTextAttribute(hStdout, FOREGROUND_RED); std::cout << "===========================================================" << std::endl; std::string resmsg = RESONE; resmsg += std::to_string(count); resmsg += RESTWO; std::cout << resmsg << std::endl; std::cout << "===========================================================" << std::endl; SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); return 0; } INIReader init_cp(char *arg) { INIReader cp(arg); if (cp.ParseError() < 0) { std::cout << "Error: Cannot parse this config file.\n" << std::endl; exit(1); } return cp; } ================================================ FILE: nvd.cpp ================================================ /* nvd.cpp DetExploit program file related to NVD. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #include "detexploit.hpp" std::map nvd_download_vulndata(HANDLE hStdout) { std::string Url = ""; std::string str = ""; std::vector tmp; std::map product_dict; std::cout << NVD_DOWNLOAD_INTRO << std::endl; for (int y = 2010; y < 2020; y++) { Url = "https://raw.githubusercontent.com/moppoi5168/VulnData/cf6e0e47cf14ee8866c7ddbd1bd9fb226779a3da/NVD-DETEXPLOIT/NVDVULN_"; Url += std::to_string(y); Url += ".detexploit"; URLDownloadToFile(0, Url.c_str(), _T("nvd_temp.xml"), 0, 0); std::ifstream ifs("nvd_temp.xml"); while (getline(ifs, str)) { tmp = split(str, "/,/,/,/"); try { product_dict[tmp[0]] = tmp[1]; } catch (...) { continue; } } } std::cout << NVD_DOWNLOAD_SUCCESS << std::endl; std::cout << "===========================================================" << std::endl; return product_dict; } std::map nvd_scan(std::map nvd_vulndata, std::map installed) { std::map resultdict; std::string level = ""; VulnInfo vinfo; for (auto fit = nvd_vulndata.begin(); fit != nvd_vulndata.end(); fit++) { for (auto nit = installed.begin(); nit != installed.end(); nit++) { if ((*fit).first == (*nit).first && (*fit).second == (*nit).second) { level = determine_severity(NVD, "NOEXT"); vinfo.version = (*fit).second; vinfo.is_edb = true; vinfo.is_jvn = false; vinfo.is_nvd = false; vinfo.is_winupd = false; vinfo.severity = level; resultdict[(*fit).first] = vinfo; std::cout << "===========================================================" << std::endl; std::cout << DETECT_ALERT << std::endl; std::cout << APP_NAME << (*fit).first << " >>" << std::endl; std::cout << APP_VERSION << (*fit).second << " >>" << std::endl; std::cout << DETECT_USING_NVD << std::endl; std::cout << OBJECT_LEVEL << level << " >>" << std::endl; std::cout << "===========================================================" << std::endl; } } } return resultdict; } ================================================ FILE: report.cpp ================================================ /* report.cpp DetExploit program file related to scan result report. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #include "detexploit.hpp" std::string determine_severity(std::string data_src, std::string ext) { if (data_src == "ExploitDB") { std::string rv = LEVEL_DANGER; return rv; } else if (data_src == "WinUpdate") { if (ext == "NOEXT" || ext.find("KB") == std::string::npos) { std::string rv = LEVEL_WARNING; return rv; } /* TODO: Retrieve informations from Windows Update Catalog, to determine update is important or not. */ std::string rv = LEVEL_WARNING; return rv; } else if (data_src == "JVN") { std::string rv = LEVEL_CAUTION; return rv; } else if (data_src == "NVD") { std::string rv = LEVEL_CAUTION; return rv; } else { std::string rv = "Error"; return rv; } } void generate_report(INIReader cp, std::string session_id, std::string scan_starttime, std::string scan_endtime, std::map resultdict) { std::string rformat = std::string(cp.Get("general", "report_format", "HTML")); std::string hostname = ghostname(); std::string templ = ""; if (rformat == "HTML") { std::ifstream ifs("resources/report_template.html"); if (ifs.fail()) { std::cerr << "Error: Cannot load resources/report_template.html" << std::endl; exit(1); } std::string templ((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); } else if (rformat == "Markdown") { std::ifstream ifs("resources/report_template.md"); if (ifs.fail()) { std::cerr << "Error: Cannot load resources/report_template.md" << std::endl; exit(1); } std::string templ((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); } else if (rformat == "PlainText") { std::ifstream ifs("resources/report_template.txt"); if (ifs.fail()) { std::cerr << "Error: Cannot load resources/report_template.txt" << std::endl; exit(1); } std::string templ((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); } else { std::cout << REPORT_FORMAT_READ_ERROR_ONE << std::endl; std::cout << REPORT_FORMAT_READ_ERROR_TWO << std::endl; std::ifstream ifs("resources/report_template.html"); if (ifs.fail()) { std::cerr << "Error: Cannot load resources/report_template.html" << std::endl; exit(1); } std::string templ((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); } std::string row = ""; std::string detect_using_exploitdb = ""; std::string attack_code_exists = ""; std::string detect_using_jvn = ""; std::string detect_using_nvd = ""; std::string is_windows_update = ""; std::string tdid = ""; for (auto it = resultdict.begin(); it != resultdict.end(); it++) { VulnInfo vuln_i = (*it).second; std::string app_name = (*it).first; std::string app_version = vuln_i.version; if ((*it).second.is_edb) { detect_using_exploitdb = "〇"; attack_code_exists = "〇"; } else { detect_using_exploitdb = "×"; attack_code_exists = "Unknown"; } if ((*it).second.is_jvn) { detect_using_jvn = "〇"; } else { detect_using_jvn = "×"; } if ((*it).second.is_nvd) { detect_using_nvd = "〇"; } else { detect_using_nvd = "×"; } if ((*it).second.is_winupd) { is_windows_update = "〇"; } else { is_windows_update = "×"; } if ((*it).second.severity == "DANGER") { tdid = "danger"; } else if ((*it).second.severity == "WARINING") { tdid = "warning"; } else if ((*it).second.severity == "CAUTION") { tdid = "caution"; } else { tdid = "unknown"; } std::string ext = ""; std::string conts = ""; if (rformat == "PlainText") { ext = ".txt"; conts = "!!CONTS_PlainText!!"; // conts{boost::format("\n [%1% v%2%] - %3%\n Detected using ExploitDB: %4%\n Detected using JVN: %5%\n Detected using NVD: %6%\n Is it Windows Update: %7%\n Attack Code Existence: %8%\n ") % app_name % app_version % (*it).second.severity % detect_using_exploitdb % detect_using_jvn % detect_using_nvd % is_windows_update % attack_code_exists}; row = row + conts; } else if (rformat == "Markdown") { ext = ".md"; conts = "!!CONTS_Markdown!!"; // conts{boost::format("\n ### %1% v%2%\n - Level: %3%\n - Detected by ExploitDB: %4%\n - Detected by JVN: %5%\n - Detected by NVD: %6%\n - Is it Windows Update: %7%\n - Attack Code Existence: %8%\n ") % app_name % app_version % (*it).second.severity % detect_using_exploitdb % detect_using_jvn % detect_using_nvd % is_windows_update % attack_code_exists}; row = row + conts; } else { ext = ".html"; conts = "!!CONTS_HTML!!"; // conts{boost::format("\n \n %2%\n %3%\n %4%\n %5%\n %6%\n %7%\n %8%\n %9%\n \n ") % tdid % (*it).second.severity % app_name % app_version % detect_using_exploitdb % detect_using_jvn % detect_using_nvd % is_windows_update % attack_code_exists}; row = row + conts; } // std::string report = boost::format(templ) % DETEXPLOIT_VERSION % hostname % scan_starttime % scan_endtime % "NOTAVAIL" % session_id % LANGPACK_SIGNATURE % row; std::string report = "!!REPORT!!" + conts; std::string filename = "detexploit_report_" + session_id + ext; std::ofstream rfile; rfile.open(filename, std::ios::out); if (!rfile) { std::cout << "Error: Cannot generate report. Please check permission settings, and retry." << std::endl; exit(1); } rfile << report << std::endl; } } ================================================ FILE: resources/default.ini ================================================ ########################################################### # default.ini # This is BACKUP of config.ini, DO NOT EDIT!!!! # DetExploit (https://github.com/moppoi5168/DetExploit) # Licensed by GPL License ########################################################### [general] # DetExploit Language Settings (Default Value: en) lang = ja # DetExploit will automaticly delete vulnerability data if you set True here. (Default Value: True) do_not_save_vulndata = True # If you want to scan also for the operating system update, set True here. (Default Value: True) os_update_scan = True # The scan report format of DetExploit. (Default Value: HTML) report_format = HTML [exploitdb] # If you want to use ExploitDB as source of vulnerability data, set True here. (Default Value: True) use_exploitdb = True # File name that DetExploit saves ExploitDB vulnerability data. (Default Value: exploitdb.detexploit) vulndata_filename = exploitdb.detexploit [jvn] # If you want to use JVN as source of vulnerability data, set True here. (Default Value: True) use_jvn = True # The time range of vulnerability data from JVN. # If you make it longer, time that is required to process will also be longer. (Default Value: 2010, 2019) data_from = 2010 data_to = 2019 [nvd] # If you want to use JVN as source of vulnerability data, set True here. (Default Value: True) use_nvd = True # The time range of vulnerability data from NVD. # If you make it longer, time that is required to process will also be longer. (Default Value: 2010, 2019) data_from = 2010 data_to = 2019 ================================================ FILE: resources/langpack/en_langdata.hpp ================================================ /* en_langdata.hpp English language pack of DetExploit. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #define WELCOME_MESSAGE " Hello, W0rld!! Welcome to DetExploit v1.4-alpha :D" /* Used in exploitdb.py */ #define EXPLOITDB_DOWNLOAD_INTRO " Downloading vulnerability data from ExploitDB GitHub repo." #define EXPLOITDB_DOWNLOAD_SUCCESS " Download complete." #define EXPLOITDB_DOWNLOAD_FAILED " Error: ExploitDB vulnerability data download has failed!!!" #define EXPLOITDB_EXTRACT_WIN " Extracting Windows platform exploit from " #define EXPLOITDB_EXTRACT_SUCCESS " Extracted successfully." /* Used in jvn.py */ #define JVN_DOWNLOAD_INTRO " Downloading vulnerability data from JVN." #define JVN_DOWNLOAD_ALERT_ONE " This may need a long time to process." #define JVN_DOWNLOAD_ALERT_TWO " Do not exit the program." #define JVN_DOWNLOAD_PROGRESS " Successfully Downloaded: " #define JVN_DOWNLOAD_SUCCESS " Download complete." /* Used in nvd.py */ #define NVD_DOWNLOAD_INTRO " Downloading vulnerability data from NVD." #define NVD_DOWNLOAD_SUCCESS " Download complete." /* Used in winupdate.py */ #define WINUPD_SCAN_INTRO " Running update searcher script to gather not-installed update." /* Used in * (Scan Phase) */ #define DETECT_ALERT " << ALERT :: VULNERABLE APPLICATION DETECTED >>" #define DETECT_UPDATE_ALERT " << ALERT :: AVAILABLE WINDOWS UPDATE DETECTED >>" #define APP_NAME " << Application Name: " #define APP_VERSION " << Application Version:" #define UPDATE_NAME " << Update Name: " #define DETECT_USING_EXPLOITDB " << Used database: ExploitDB >>" #define DETECT_USING_JVN " << Used database: Japan Vulnerability Notes >>" #define DETECT_USING_NVD " << Used database: National Vulnerability Database >>" #define OBJECT_LEVEL " << Level:" /* Used in report.py */ #define LEVEL_DANGER "DANGER" #define LEVEL_WARNING "WARNING" #define LEVEL_CAUTION "CAUTION" #define EDB "ExploitDB" #define JVN "JVN" #define NVD "NVD" #define REPORT_FORMAT_READ_ERROR_ONE "Error: Scan report format detemination failed. (Check config.ini)" #define REPORT_FORMAT_READ_ERROR_TWO "Error: Default value will be used (HTML)." #define REPORT_OUTPUT_INFO_ONE " Report has been saved at ../reports/detexploit_report_" #define REPORT_OUTPUT_INFO_TWO " !!!" /* GUI */ #define FIRST_MSG "Please click scan button to start." #define OP_START "Operation has been started." #define EXPLOITDB_EXTRACT_GUI "Extracting Windows vulnerability from data." #define EXPLOITDB_PARSE "Parsing vulnerability data." #define WMI_APP_RET "Retrieving application data from WMI." #define REG_APP_RET "Retrieving application data from Windows Registry." #define SCAN_MSG_ONE "Comparing fetched data and installed application list." #define SCAN_MSG_TWO "Checking available Windows Updates." #define SCAN_END "Done." #define GEN_REPORT "Generating report in specified format." #define RESONE " RESULT: " #define RESTWO " vulnerable application or update detected!!" #define LANGPACK_SIGNATURE "DetExploit English LP" ================================================ FILE: resources/langpack/ja_langdata.hpp ================================================ /* ja_langdata.hpp English language pack of DetExploit. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #define WELCOME_MESSAGE " Hello, W0rld!! DetExploit v1.4-alphaへようこそ! :D" /* Used in exploitdb.py */ #define EXPLOITDB_DOWNLOAD_INTRO " ExploitDBから脆弱性情報をダウンロードしています。" #define EXPLOITDB_DOWNLOAD_SUCCESS " ダウンロード完了。" #define EXPLOITDB_DOWNLOAD_FAILED " エラー: ExploitDBの脆弱性情報ダウンロードが失敗しました。" #define EXPLOITDB_EXTRACT_WIN " 次のファイルからWindows環境の脆弱性のみを抽出しています: " #define EXPLOITDB_EXTRACT_SUCCESS " 抽出に成功しました。" /* Used in jvn.py */ #define JVN_DOWNLOAD_INTRO " JVNから脆弱性情報をダウンロードしています。" #define JVN_DOWNLOAD_ALERT_ONE " この処理には時間がかかる可能性があります。" #define JVN_DOWNLOAD_ALERT_TWO " プログラムを終了しないでください。" #define JVN_DOWNLOAD_PROGRESS " ダウンロード成功: " #define JVN_DOWNLOAD_SUCCESS " ダウンロード完了。" /* Used in nvd.py */ #define NVD_DOWNLOAD_INTRO " NVDから脆弱性情報をダウンロードしています。" #define NVD_DOWNLOAD_SUCCESS " ダウンロード完了。" /* Used in winupdate.py */ #define WINUPD_SCAN_INTRO " インストールされていないアップデートを検索しています。" /* Used in * (Scan Phase) */ #define DETECT_ALERT " << 警告 :: 脆弱なアプリケーションを検知しました >>" #define DETECT_UPDATE_ALERT " << 警告 :: インストールされていないWindows Updateを検知しました >>" #define APP_NAME " << アプリケーション名: " #define APP_VERSION " << アプリケーションのバージョン:" #define UPDATE_NAME " << アップデート名: " #define DETECT_USING_EXPLOITDB " << 使用したデータベース: ExploitDB >>" #define DETECT_USING_JVN " << 使用したデータベース: Japan Vulnerability Notes >>" #define DETECT_USING_NVD " << 使用したデータベース: National Vulnerability Database >>" #define OBJECT_LEVEL " << オブジェクトレベル:" /* Used in report.py */ #define LEVEL_DANGER "危険" #define LEVEL_WARNING "警告" #define LEVEL_CAUTION "注意" #define EDB "ExploitDB" #define JVN "JVN" #define NVD "NVD" #define REPORT_FORMAT_READ_ERROR_ONE "エラー: スキャンレポート出力方式が正しく設定されていません。config.iniを確認してください。" #define REPORT_FORMAT_READ_ERROR_TWO "エラー: 初期値(HTML)が使用されます。" #define REPORT_OUTPUT_INFO_ONE " レポートは次のファイルに正常に出力されました: ../reports/detexploit_report_" #define REPORT_OUTPUT_INFO_TWO " " /* GUI */ #define FIRST_MSG "スキャンボタンをクリックしてスタートしてください。" #define OP_START "オペレーションが開始しました。" #define EXPLOITDB_EXTRACT_GUI "Windowsの脆弱性をデータから抽出しています。" #define EXPLOITDB_PARSE "ExploitDB脆弱性データを解析しています。" #define WMI_APP_RET "WMIからアプリケーション情報を取得しています。" #define REG_APP_RET "レジストリからアプリケーション情報を取得しています。" #define SCAN_MSG_ONE "外部の情報とローカルマシンの情報を使用してスキャンしています。" #define SCAN_MSG_TWO "未適用のWindows Updateを検索しています。" #define SCAN_END "完了。" #define GEN_REPORT "指定されたフォーマットでレポートを出力中。" #define RESONE " 結果: " #define RESTWO " 個の脆弱なアプリケーション、未インストールのアップデートが検知されました。" #define LANGPACK_SIGNATURE "DetExploit Japanese LP" ================================================ FILE: resources/report_template.html ================================================ DetExploit Report

Scan Overview

  • Machine Name: %1%
  • Scan started at: %2%
  • Scan ended at: %3%
  • Detected Vulnerable App or Update: %4%
  • DetExploit Version: %5%

Flags

  • Session ID: %6%
  • Language Pack: %7%
  • -
  • -
  • -
%8%
Level Object Name Object Version ExploitDB MyJVN API NVD Windows Update Attack Code Exists
================================================ FILE: resources/report_template.md ================================================ # DetExploit Scan Report ## Scan Overview - Machine Name: %1% - Scan started at: %2% - Scan ended at: %3% - Detected vulnerability or update: %4% - Platform: %5% ## Flags - Session ID: %6% - Language Pack: %7% ## Result %8% ================================================ FILE: resources/report_template.txt ================================================ ################################################## # DetExploit Scan Report # ################################################## ## Scan Overview ################################# - Machine Name: %1% - Scan started at: %2% - Scan ended at: %3% - Detected Vulnerable App or Update: %4% - DetExploit Version: %5% ################################################## ## Flags ######################################### - Session ID: %6% - Language Pack: %7% ################################################## ## Result ######################################## %8% ################################################## ================================================ FILE: utils.cpp ================================================ /* utils.cpp DetExploit program file for utilities used in entire program. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 16383 #include "detexploit.hpp" static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; std::string ghostname() { char hostname[256]; DWORD hostnameLength = 256; GetComputerName(hostname, &hostnameLength); return std::string(hostname); } bool checkFileExistence(const std::string& str) { std::ifstream ifs(str); return ifs.is_open(); } std::vector split(const std::string& src, const char* delim) { std::vector vec; std::string::size_type len = src.length(); for (std::string::size_type i = 0, n; i < len; i = n + 1) { n = src.find_first_of(delim, i); if (n == std::string::npos) { n = len; } vec.push_back(src.substr(i, n - i)); } return vec; } std::string join(const std::vector& v, const char* delim) { std::string s = ""; if (!v.empty()) { s += v[0]; for (decltype(v.size()) i = 1, c = v.size(); i < c; ++i) { if (delim) s += delim; s += v[i]; } } return s; } std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { std::string ret = ""; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } return ret; } bool config_test() { return false; } ================================================ FILE: winupdate.cpp ================================================ /* winupdate.cpp DetExploit program file related to Windows Update. DetExploit (https://github.com/moppoi5168/DetExploit) Licensed by GPL License */ #include "detexploit.hpp"