0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ollama + LangChain + Nmapで遊んでみた

Last updated at Posted at 2025-11-26

OllamaとLangChain、Nmapを利用して遊んでみました。

Nmapの情報を、StructuredOutputで出力しようとしました。
LLMが処理しやすいように、構造化されたXMLで、Nmapの結果を出力しましたが、すべてのポートは取得できなかったです。
まぁ、プログラムで処理できるものは、プログラムでやったほうが確実ですしね...

Nmapコマンド

nmap -A -sT -v -T 4 [IP Address] -oX nmap.xml

結果

>> python sample_code.py
name='localhost' type='loopback' vendor='Linux' family='IPv4' generation='2.6.32-71-generic' cpes=['cpe:/o:linux:linux:2.6.32-71-generic'] ports=[PortInfo(port=22, protocol='tcp', service_name='ssh'), PortInfo(port=80, protocol='tcp', service_name='http')]

全体コード

import subprocess
from typing import List

from pydantic import BaseModel, Field
from langchain.chat_models import init_chat_model


class PortInfo(BaseModel):
    """Port Info
    """
    port: int = Field(..., description="Open Port Number")
    protocol: str = Field(..., description="Open Port Protocol")
    service_name: str = Field(..., description="Open Port Service Name")


class OSInfo(BaseModel):
    """OS Info
    """
    name: str = Field(..., description="OS Name")
    type: str = Field(..., description="OS Type")
    vendor: str = Field(..., description="OS Vendor")
    family: str = Field(..., description="OS Family")
    generation: str = Field(..., description="OS Generation")
    cpes: List[str] = Field(..., description="OS Common Platform Enumeration")
    ports: List[PortInfo] = Field(..., description="Open Ports")


def port_scan(ip_address: str) -> str:
    """Run Nmap
    """
    cmd = ['nmap', '-A', '-sT', '-v', '-T', '4', ip_address, '-oX', 'nmap.xml']
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    return result.stdout


def main(ip_address: str):
    model = init_chat_model(
        model="ollama:llama3.2:latest",
        base_url="http://[Ollama Server IP Address]:11434",
        temperature=0
    )

    structured_model = model.with_structured_output(OSInfo)

    nmap_output = port_scan(ip_address)

    prompt = f"""以下のNmap出力結果から、OSとポートの情報を抽出してください。
    ポート情報は、<port>タグを全て見つけて、state="open"の全てのポートを抽出してください。

    Nmap出力:
    {nmap_output}

    ** ポートはすべてのポートを抽出してください。 **
    """

    scan_result: OSInfo = structured_model.invoke(prompt)

    print(scan_result)


if __name__ == "__main__":
    main("[Target IP Address]")
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?