Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
inquisitor — recon-ng と Maltego に触発された、意見の強い組織中心の OSINT フットプリンティング | Kitploit
ツール/GitHubGitHub/penafieljlm/inquisitor
OSINT (オープンソースインテリジェンス)偵察DNSおよびサブドメイン列挙情報収集脅威インテリジェンスメール収集
GitHubpenafieljlm/inquisitor

inquisitor

recon-ng と Maltego に触発された、意見の強い組織中心の OSINT フットプリンティング

リポジトリを見る
1805759年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Inquisitor

お知らせ

このプロジェクトは部分的にしか完成しておらず、以下のブログ記事で説明されている機能の多くはまだ実装されていません:https://penafieljlm.com/2017/07/14/inquisitor/

Inquisitorは、オープンソースインテリジェンス(OSINT)ソースを利用して企業や組織に関する情報を収集するためのシンプルなツールです。Maltegoやrecon-ngの動作から強くインスピレーションを受けており、それらのツールの機能の一部をほぼ再実装しつつ、アセットタイプに意見ベースの意味論の追加レイヤーを重ねることで、使いやすいワークフローを実現しています。

Inquisitorの主な機能は次のとおりです。

  1. アセットの所有権ラベルを連鎖的に適用する機能(例:登録者名がターゲット組織に属することがわかっている場合、その名前で登録されたホストやネットワークはターゲット組織に属するものとしてマークされる)
  2. GoogleやShodanなどのオープンソースに問い合わせることで、アセットを他の潜在的な関連アセットに変換する機能
  3. ズーム可能なパックレイアウトを通じてそれらのアセットの関係を可視化する機能

コンセプト

Inquisitorのコンセプト全体は、ターゲット組織について既にわかっている情報に基づいてオープンソースから情報を抽出するという考えに基づいています。Inquisitorの文脈では、これらは「トランスフォーム」と呼ばれます。また、whoisやインターネットレジストリなどのオープンソースからも取得可能なメタデータに基づいて、既知のアセットから関連情報を即座に取得することもできます。

これらのコンセプトについては、以下のブログ記事で詳しく説明されています:https://penafieljlm.com/2017/07/14/inquisitor/

インストール

Inquisitorをインストールするには、リポジトリをクローンし、そのディレクトリに入り、インストールスクリプトを実行します。``` pip install Cython click git clone [email protected]:penafieljlm/inquisitor.git cd inquisitor python setup.py install

root@kitploit:~
## 使用法

Inquisitor には、`scan`、`status`、`classify`、`dump`、`visualize` の5つの基本コマンドがあります。```
usage: inq [-h] {scan,status,classify,dump,visualize} ...

optional arguments:
  -h, --help            show this help message and exit

command:
  {scan,status,classify,dump,visualize}
                        The action to perform.
    scan                Search OSINT sources for intelligence based on known
                        assets belonging to the target.
    status              Prints out the current status of the specified
                        intelligence database.
    classify            Classifies an existing asset as either belonging or
                        not belonging to the target. Adds a new asset with the
                        specified classification if none is present.
    dump                Dumps the contents of the database into a JSON file
    visualize           Create a D3.js visualization based on the contents of
                        the specified intelligence database.

Scan

スキャンモードでは、ツールはインテリジェンスデータベース内のすべてのアセットに対して利用可能なすべてのトランスフォームを実行します。以下に示すさまざまなOSINTソースのAPIキーを作成し、スクリプトに提供してください。そうしないと、それらのソースを使用するトランスフォームがスキップされます。また、データベースに所有アセットがないと変換するものが何もないため、最初にclassifyコマンドを使用していくつかの既知の所有ターゲットアセットをインテリジェンスデータベースにシードしてください。``` usage: inq scan [-h] [--google-dev-key GOOGLE_DEV_KEY] [--google-cse-id GOOGLE_CSE_ID] [--google-limit GOOGLE_LIMIT] [--shodan-api-key SHODAN_API_KEY] [--shodan-limit SHODAN_LIMIT] DATABASE

positional arguments: DATABASE The path to the intelligence database to use. If specified file does not exist, a new one will be created.

optional arguments: -h, --help show this help message and exit --google-dev-key GOOGLE_DEV_KEY Specifies the developer key to use to query Google Custom Search. Visit the Google APIs Console (http://code.google.com/apis/console) to get an API key. If notspecified, the script will simply skip asset transforms that involve Google Search. --google-cse-id GOOGLE_CSE_ID Specifies the custom search engine to query. Visit the Google Custom Search Console (https://cse.google.com/cse/all) to create your own Google Custom Search Engine. If not specified, the script will simply skip asset transforms that involve Google Search. --google-limit GOOGLE_LIMIT The number of pages to limit Google Search to. This is to avoid exhausting your daily quota. --shodan-api-key SHODAN_API_KEY Specifies the API key to use to query Shodan. Log into your Shodan account (https://www.shodan.io/) and look at the top right corner of the page in order to view your API key. If not specified, the script will simply skip asset transforms that involve Shodan. --shodan-limit SHODAN_LIMIT The number of pages to limit Shodan Search to. This is to avoid exhausting your daily quota.

root@kitploit:~
### ステータス

ステータスモードでは、ツールはスキャンデータベースのステータスの簡単な要約を出力します。```
usage: inq status [-h] [-s] DATABASE

positional arguments:
  DATABASE      The path to the intelligence database to use. If specified
                file does not exist, a new one will be created.

optional arguments:
  -h, --help    show this help message and exit
  -s, --strong  Indicates if the status will be based on the strong ownership
                classification.

Classify

classify モードでは、手動でアセットを追加したり、Intelligence Database 内の既存のアセットを再分類することができます。このコマンドを使用して、既知の所有ターゲットアセットで Intelligence Database をシードする必要があります。``` usage: inq classify [-h] [-ar REGISTRANT [REGISTRANT ...]] [-ur REGISTRANT [REGISTRANT ...]] [-rr REGISTRANT [REGISTRANT ...]] [-ab BLOCK [BLOCK ...]] [-ub BLOCK [BLOCK ...]] [-rb BLOCK [BLOCK ...]] [-ah HOST [HOST ...]] [-uh HOST [HOST ...]] [-rh HOST [HOST ...]] [-ae EMAIL [EMAIL ...]] [-ue EMAIL [EMAIL ...]] [-re EMAIL [EMAIL ...]] [-al LINKEDIN [LINKEDIN ...]] [-ul LINKEDIN [LINKEDIN ...]] [-rl LINKEDIN [LINKEDIN ...]] DATABASE

positional arguments: DATABASE The path to the intelligence database to use. If specified file does not exist, a new one will be created.

optional arguments: -h, --help show this help message and exit -ar REGISTRANT [REGISTRANT ...], --accept-registrant REGISTRANT [REGISTRANT ...] Specifies a registrant to classify as accepted. -ur REGISTRANT [REGISTRANT ...], --unmark-registrant REGISTRANT [REGISTRANT ...] Specifies a registrant to classify as unmarked. -rr REGISTRANT [REGISTRANT ...], --reject-registrant REGISTRANT [REGISTRANT ...] Specifies a registrant to classify as rejected. -ab BLOCK [BLOCK ...], --accept-block BLOCK [BLOCK ...] Specifies a block to classify as accepted. -ub BLOCK [BLOCK ...], --unmark-block BLOCK [BLOCK ...] Specifies a block to classify as unmarked. -rb BLOCK [BLOCK ...], --reject-block BLOCK [BLOCK ...] Specifies a block to classify as rejected. -ah HOST [HOST ...], --accept-host HOST [HOST ...] Specifies a host to classify as accepted. -uh HOST [HOST ...], --unmark-host HOST [HOST ...] Specifies a host to classify as unmarked. -rh HOST [HOST ...], --reject-host HOST [HOST ...] Specifies a host to classify as rejected. -ae EMAIL [EMAIL ...], --accept-email EMAIL [EMAIL ...] Specifies a email to classify as accepted. -ue EMAIL [EMAIL ...], --unmark-email EMAIL [EMAIL ...] Specifies a email to classify as unmarked. -re EMAIL [EMAIL ...], --reject-email EMAIL [EMAIL ...] Specifies a email to classify as rejected. -al LINKEDIN [LINKEDIN ...], --accept-linkedin LINKEDIN [LINKEDIN ...] Specifies a LinkedIn Account to classify as accepted. -ul LINKEDIN [LINKEDIN ...], --unmark-linkedin LINKEDIN [LINKEDIN ...] Specifies a LinkedIn Account to classify as unmarked. -rl LINKEDIN [LINKEDIN ...], --reject-linkedin LINKEDIN [LINKEDIN ...] Specifies a LinkedIn Account to classify as rejected.

root@kitploit:~
### Dump

ダンプモードでは、インテリジェンスデータベースの内容を人間が読めるJSONファイルにダンプできます。```
usage: inq dump [-h] [-j FILE] [-a] DATABASE

positional arguments:
  DATABASE              The path to the intelligence database to use. If
                        specified file does not exist, a new one will be
                        created.

optional arguments:
  -h, --help            show this help message and exit
  -j FILE, --json FILE  The path to dump the JSON file to. Overwrites existing
                        files.
  -a, --all             Include rejected assets in dump.

可視化

可視化モードでは、Intelligence Repository の階層的な可視化を取得できます。``` usage: inq visualize [-h] [-l] DATABASE

positional arguments: DATABASE The path to the intelligence database to use. If specified file does not exist, a new one will be created.

optional arguments: -h, --help show this help message and exit -l, --last Simply open the last visualization generated instead of creating a new one.

root@kitploit:~
## ワークフロー

これでInquisitorの基本機能を理解したところで、*実際の*使い方を学びましょう。Inquisitorは以下の手順を念頭に置いて作成されています。

### シーディング

このステップでは、インテリジェンスデータベースにはまだ何もデータがありません。どこからか始めなければならないので、ターゲット組織に属することがわかっている資産でデータベースをシードしてください。これを行うには、`classify`コマンドを使用します。

### スキャン

データベースにターゲット組織に属することがわかっている資産が含まれるようになりました。次にスキャンを進めることができます。これを行うには、`scan`コマンドを使用します。

インテリジェンスデータベースで`scan`コマンドを呼び出すと、Inquisitorは`accepted`として分類された資産の`transform`メソッドを実行します。スキャンが完了すると、ターゲット組織に潜在的に属する可能性のあるさらなる資産が得られます。

新しい資産が得られなかった場合は、インテリジェンスデータベースに新しい情報をシードするか、レポーティングステップに進んでプロセスを完了することができます。

### 分類

Inquisitorは自動的に資産を分類しますが、実際にはターゲット組織に属するいくつかの資産を見逃す可能性があります。

このような場合、データベースの内容を確認し、手動で資産を分類する必要があります。通常、**Registrant**(登録者)資産に注意を払う必要があります。この資産タイプでは所有権を自動的に判断する方法がないためです。また、他のほとんどの資産タイプは、ターゲットに属するかどうかを判断するためにRegistrant資産の所有権分類に依存しているため、Registrant資産に注意を払うことが重要です。さらに、そもそもRegistrant資産はそれほど多くないため、それらを選別するのはそれほど難しくありません。

### レポーティング

`visualize`コマンドまたは`dump`コマンドを使用して、ターゲット組織に属する資産の可視化を生成できます。

## デモ

ツールの動作を示すビデオデモを以下のリンクで公開しています:https://drive.google.com/open?id=0B_O70BVu38TRclo5dWRBWkdTTWc

ただし、無料の画面録画ソフトが最大10分までしか録画できないため、scanコマンドの実行を完全に録画することができませんでした。

## 開発

Inquisitorプロジェクトは以下の形式で構成されています:```
.
|-- README.md
|-- inquisitor
|   |-- __init__.py
|   |-- assets
|   |   |-- __init__.py
|   |   |-- block.py
|   |   |-- email.py
|   |   |-- host.py
|   |   |-- linkedin.py
|   |   `-- registrant.py
|   |-- extractors
|   |   |-- __init__.py
|   |   `-- emails.py
|   `-- sources
|       |-- __init__.py
|       |-- google_search.py
|       `-- shodan_search.py
|-- inq
|-- report
|   `-- index.html
|-- setup.py
`-- tests
    |-- __init__.py
    `-- test_inq.py

これは assets、extractors、sources という3つの主要モジュールから構成されています。メインスクリプトは inq です。

開発者としては、主に新しい種類のアセットをシステムに追加することに関心があるでしょう。そのため、この開発者ガイドは主にその点に焦点を当てています。

リポジトリ

実際にアセットクラスを実装する前に、まずインテリジェンスデータベースとの対話方法を理解する必要があります。これは、アセットクラスから関連するアセットを導出する際にデータベースとやり取りするためです。

インテリジェンスデータベースのソースコードは inquisitor/__init__.py ファイルに格納されています。インテリジェンスデータベースの論理ラッパーの実際の名前は IntelligenceRepository と呼ばれています。

アセットクラスからは IntelligenceRepository.get_asset_string 関数を呼び出すだけで済みます。新しいアセットをインテリジェンスデータベースに追加するのは、inq スクリプト内の scan モジュールの責任だからです。この関数は主に、アセットのインスタンスを作成したり、存在する場合はデータベースから取得したりするために使用します。この関数は、アセットクラスの related 関数や transform 関数からアセットを返す際に重要です。新しいアセットオブジェクトの作成は、初期化中にネットワークリソースを使用するものもあるため、コストがかかるからです。``` Function

IntelligenceRepository.get_asset_string(asset_type, identifier, create=False, store=False)

Description

root@kitploit:~
Retrieves the primary key and asset object for the asset with the provided 
type and identifier.

Parameters

root@kitploit:~
asset_type: class, required

    The type of the asset to retrieve from the Intelligence Database. You
    will actually have to pass the class object of the asset type you want
    to retrieve.

identifier: any, required

    The identifier of the asset to retrieve. Consider the identifier as the
    unique attribute of an asset object. As for which attribute is to be
    used to identify an asset, it depends on the contents of the OBJECT_ID
    variable in the asset module.

create: bool, optional, default=False

    When no matching asset object is found, a new one will be created and 
    returned if this parameter is set to True. The new asset will not
    necessarily be stored in the Intelligence Database unless specified
    using the "store" parameter. However, I suggest you do not do this as
    adding assets to the Intelligence Database is the responsibility of
    another module.

store: bool, optional, default=False

    When a new asset is created when none is found, the new one will be
    stored in the Intelligence Database. As said previously, I suggest that
    you do not do this as adding assets to the Intelligence Database is the
    responsibility of another module.

Returns

root@kitploit:~
A two-element tuple where the first element is the database primary key of 
the element returned, and the second element is the deserialized asset 
object retrieved from the database.

None if the asset was not found.

If the asset was not found and the create flag was set to True, the primary
key member of the tuple will be set to None.
root@kitploit:~
### アセット

新しいアセットタイプを作成するには、`inquisitor/assets` ディレクトリ内に新しいファイルを作成し、以下のスケルトンコードを貼り付けてください:```python
import inquisitor.assets

class ASSET_NAMEValidateException(Exception):
    pass

def canonicalize(ASSET_IDENTIFIER):
    return ASSET_IDENTIFIER

def main_classify_args(parser):
    parser.add_argument(
        '-aASSET_NAME_LETTER', '--accept-ASSET_NAME',
        metavar='ASSET_NAME',
        type=canonicalize,
        nargs='+',
        help='Specifies a ASSET_NAME to classify as accepted.',
        dest='ASSET_NAMEs_accepted',
        default=list(),
    )
    parser.add_argument(
        '-uASSET_NAME_LETTER', '--unmark-ASSET_NAME',
        metavar='ASSET_NAME',
        type=canonicalize,
        nargs='+',
        help='Specifies a ASSET_NAME to classify as unmarked.',
        dest='ASSET_NAMEs_unmarked',
        default=list(),
    )
    parser.add_argument(
        '-rASSET_NAME_LETTER', '--reject-ASSET_NAME',
        metavar='ASSET_NAME',
        type=canonicalize,
        nargs='+',
        help='Specifies a ASSET_NAME to classify as rejected.',
        dest='ASSET_NAME_rejected',
        default=list(),
    )

def main_classify_canonicalize(args):
    accepted = set(args.ASSET_NAMEs_accepted)
    unmarked = set(args.ASSET_NAMEs_unmarked)
    rejected = set(args.ASSET_NAME_rejected)
    redundant = set.intersection(accepted, unmarked, rejected)
    if redundant:
        raise ValueError(
            ('Conflicting classifications for ASSET_NAMEs '
            ': {}').format(list(redundant))
        )
    accepted = set([canonicalize(a) for a in accepted])
    unmarked = set([canonicalize(a) for a in unmarked])
    rejected = set([canonicalize(a) for a in rejected])
    return (accepted, unmarked, rejected)

class ASSET_NAME(inquisitor.assets.Asset):

    def __init__(self, ASSET_IDENTIFIER, owned=None):
        super(self.__class__, self).__init__(owned=owned)
        self.ASSET_IDENTIFIER = canonicalize(ASSET_IDENTIFIER)
        # TODO: Perform other initialization actions here

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return False
        return self.ASSET_IDENTIFIER == other.ASSET_IDENTIFIER

    def related(self, repo):
        # Prepare the results
        results = set()
        # TODO: Create related assets here based on the attributes of this asset
        # Return the results
        return results

    def transform(self, repo, sources):
        # Prepare the results
        assets = set()
        # Google Transforms
        if sources.get('google'):
            subassets = self.cache_transform_get('google', repo)
            if not subassets:
                # Acquire API
                google = sources['google']
                # TODO: Perform Google queries here and the results to 'subassets'
                # Cache The Transform
                self.cache_transform_store('google', subassets)
            assets.update(subassets)
        # Shodan Transforms
        if sources.get('shodan'):
            subassets = self.cache_transform_get('shodan', repo)
            if not subassets:
                # Acquire API
                shodan = sources['shodan']
                # TODO: Perform Google queries here and the results to 'subassets'
                # Cache The Transform
                self.cache_transform_store('shodan', subassets)
            assets.update(subassets)
        # Return the results
        return assets

    def is_owned(self, repo):
        if self.owned:
            return True
        # TODO: Automatically determine ownership based on repo contents
        return False

    def parent_asset(self, repo):
        # TODO: Return parent asset based on repo contents
        return None

REPOSITORY = 'ASSET_REPOSITORY'
ASSET_CLASS = ASSET_NAME
OBJECT_ID = 'ASSET_IDENTIFIER'

以下の文字列を適切な値に置き換えてください

  • ASSET_NAME : アセットの正式名称(例:Registrant、Hostなど)
  • ASSET_IDENTIFIER : アセットの識別子属性の名前
  • ASSET_NAME_LETTER : アセット名の小文字の最初の文字
  • ASSET_REPOSITORY : アセット名の複数形を小文字にしたもの

最後に、inquisitor/__init__.py 内の ASSET_MODULES リストにアセットを登録してください。該当のファイルから新しいアセットをインポートすることを忘れないでください。

おめでとうございます! この時点で、新しい動作するアセットタイプができました!

ただし、アセットが他のアセットタイプと関連付けられるようにするには、以下のメソッドを実装する必要があります。``` Function

root@kitploit:~
related

Description

root@kitploit:~
  Returns the set of assets directly related to the asset in question (i.e.
  those that can be derived without querying a search engine).

  When creating asset objects, make sure you use the 
  IntelligenceRepository.get_asset_string method instead of instatiating a 
  new one your self so the asset can be returned from the repository if it 
  exists.

  Set the create flag to True when calling the method in question in order
  to return a new object when one isn't found.

  Set the store flag to False as appending assets is the job of another
  module.

Parameters

root@kitploit:~
repo: IntelligenceRepository

    The Intelligence Repository that is being used in the current context.

Returns

root@kitploit:~
Set of assets directly related to the asset in question. 
root@kitploit:~
(no input provided - empty translation)```
Function

    transform

Description
  
      Returns the set of assets potentially related to the asset in question
      (i.e. those that can be derived by querying a search engine).

      You may access search engine objects through the provided sources
      parameter.

      Each search engine object has a transform method which automatically
      creates asset objects for you. You just need to provide it the repository
      and your query string, and then append the objects it returns to the set
      of assets to be returned by your asset's transform method.

Parameters

    repo: IntelligenceRepository

        The Intelligence Repository that is being used in the current context.

    sources: dict

        The list of search engine objects that are available for use.

Returns

    Set of assets potentially related to the asset in question.
    

入力:``` Function

root@kitploit:~
is_owned

Description

root@kitploit:~
 Determines if there is high confidence that this asset does indeed belong
 to the target. Usually checks for any "strong" classification tag first by
 looking at the contents of the "owned" variable, before performing
 automatic evaluation.

 Automatic evaluation depends on what type of asset you're writing. For
 example, for a Host asset, the secondary sources of determining ownership
 would include looking if its registrant is owned by the target, if it's
 parent domain is owned by the target. etc.

Parameters

root@kitploit:~
repo: IntelligenceRepository

    The Intelligence Repository that is being used in the current context.

Returns

root@kitploit:~
True it is determined with high confidence that this asset does indeed 
belong to the target.
root@kitploit:~
No input provided for translation. Please provide the actual Markdown content to translate.```
Function

    parent_asset

Description
  
     Returns the asset object that is considered the parent of this asset
     object.

Parameters

    repo: IntelligenceRepository

Returns

    The asset object that this asset falls under (e.g. a Block is under a 
    Registrant, a Host is under a Block, a Host is under another Host, an Email
    is under a Host, etc. This is primarily used for visualization.
    

上記の方法を実装した後、アセットのソースコード下部でREPOSITORY、ASSET_CLASS、OBJECT_IDの各変数を必ず設定してください。

連絡先と注意事項

スキャンモードは、関連する検索エンジンのクォータ制限により十分にテストされていません。また、このプロジェクトは1週間のハッカソンチャレンジの一環として急いで作成されたため、多くの問題が残っている可能性があります。バグを発見した場合やご質問がある場合は、issueチケットを作成するか、[email protected]までご連絡ください。

免責事項

この成果物は、Maltegoおよびrecon-ngオープンソースインテリジェンスツールによって実装されたアプローチを基にしています。私はこれらのアプローチに、既に一般的に知られているアイデア(例:whoisはドメインの所有者を教えてくれる、サブドメインは親ドメインを所有する同じ組織によって所有されている(ドメイン名ブルートフォース攻撃から推測される)、組織は自身が所有するドメイン名に対して権限を持つ、など)、または私自身の趣味として個人的な時間に考案した独自のアイデア(例:受容性評価、さまざまなトランスフォーム、分類の継承など)を補足しています。

この成果物のいかなる部分も、過去に私が雇用主のために行った業務から派生したものではありません。プロジェクト全体(概念実証を含む)はゼロから作成され、情報セキュリティコミュニティのアイデアで補強されています。

ツールをダウンロード