Add nmap command
This commit is contained in:
parent
c40c8294b3
commit
9d199f0102
2 changed files with 131 additions and 0 deletions
|
@ -20,3 +20,4 @@ python-magic~=0.4
|
|||
aiofiles~=23.2
|
||||
fuzzywuzzy[speedup]~=0.18
|
||||
tortoise-orm[asyncpg]~=0.21
|
||||
superpaste @ git+https://github.com/nexy7574/superpaste.git@e31eca6
|
||||
|
|
130
src/cogs/net.py
130
src/cogs/net.py
|
@ -3,8 +3,12 @@ import io
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import tempfile
|
||||
import time
|
||||
import typing
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
|
||||
import discord
|
||||
|
@ -14,6 +18,8 @@ from dns import asyncresolver
|
|||
from rich.console import Console
|
||||
from rich.tree import Tree
|
||||
from conf import CONFIG
|
||||
from superpaste import HstSHBackend
|
||||
from superpaste.backends import GenericFile
|
||||
|
||||
|
||||
class GetFilteredTextView(discord.ui.View):
|
||||
|
@ -346,6 +352,130 @@ class NetworkCog(commands.Cog):
|
|||
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
@commands.slash_command()
|
||||
@commands.max_concurrency(1, commands.BucketType.user)
|
||||
async def nmap(
|
||||
self,
|
||||
ctx: discord.ApplicationContext,
|
||||
target: str,
|
||||
technique: typing.Annotated[
|
||||
str,
|
||||
discord.Option(
|
||||
str,
|
||||
choices=[
|
||||
discord.OptionChoice(name="TCP SYN", value="S"),
|
||||
discord.OptionChoice(name="TCP Connect", value="T"),
|
||||
discord.OptionChoice(name="TCP ACK", value="A"),
|
||||
discord.OptionChoice(name="TCP Window", value="W"),
|
||||
discord.OptionChoice(name="TCP Maimon", value="M"),
|
||||
discord.OptionChoice(name="UDP", value="U"),
|
||||
discord.OptionChoice(name="TCP Null", value="N"),
|
||||
discord.OptionChoice(name="TCP FIN", value="F"),
|
||||
discord.OptionChoice(name="TCP XMAS", value="X"),
|
||||
],
|
||||
default="sT"
|
||||
)
|
||||
],
|
||||
treat_all_hosts_online: bool = False,
|
||||
service_scan: bool = False,
|
||||
fast_mode: bool = False,
|
||||
enable_os_detection: bool = False,
|
||||
timing: typing.Annotated[
|
||||
int,
|
||||
discord.Option(
|
||||
int,
|
||||
description="Timing template to use 0 is slowest, 5 is fastest.",
|
||||
choices=[0, 1, 2, 3, 4, 5],
|
||||
default=3
|
||||
)
|
||||
] = 3,
|
||||
ports: str = None
|
||||
):
|
||||
"""Runs nmap on a target. You cannot specify multiple targets."""
|
||||
await ctx.defer()
|
||||
if len(shlex.split(target)) > 1:
|
||||
return await ctx.respond("You cannot specify multiple targets.")
|
||||
if not shutil.which("nmap"):
|
||||
warnings.warn(
|
||||
"NMAP is not installed on this system, so the /nmap command is not enabled. "
|
||||
"If you would like to enable it, install nmap, or mount the binary as a volume in docker."
|
||||
)
|
||||
return await ctx.respond("Nmap is not installed on this system.")
|
||||
|
||||
is_superuser = os.getuid() == 0
|
||||
if technique != "T" and not is_superuser:
|
||||
return await ctx.respond("Only `TCP Connect` can be used on this system.")
|
||||
if enable_os_detection and not is_superuser:
|
||||
return await ctx.respond("OS detection is not available on this system.")
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix=f"nmap-{ctx.user.id}-{ctx.message.created_at.timestamp():.0f}") as tmp:
|
||||
tmp_dir = Path(tmp)
|
||||
args = [
|
||||
"nmap",
|
||||
"-oA",
|
||||
str(tmp_dir.resolve() / target),
|
||||
"-T",
|
||||
str(timing),
|
||||
"-s" + technique,
|
||||
]
|
||||
if treat_all_hosts_online:
|
||||
args.append("-Pn")
|
||||
if service_scan:
|
||||
args.append("-sV")
|
||||
if fast_mode:
|
||||
args.append("-F")
|
||||
if ports:
|
||||
args.extend(("-p", ports))
|
||||
if enable_os_detection:
|
||||
args.append("-O")
|
||||
args.append(target)
|
||||
|
||||
await ctx.respond(
|
||||
embed=discord.Embed(
|
||||
title="Running nmap...",
|
||||
description="Command:\n"
|
||||
"```{}```".format(shlex.join(args)),
|
||||
)
|
||||
)
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*args,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
_, stderr = await process.communicate()
|
||||
files = [discord.File(x, filename=x.name + ".txt") for x in tmp_dir.iterdir()]
|
||||
if not files:
|
||||
if len(stderr) <= 4089:
|
||||
return await ctx.edit(
|
||||
embed=discord.Embed(
|
||||
title="Nmap failed.",
|
||||
description="```\n" + stderr.decode() + "```",
|
||||
color=discord.Color.red()
|
||||
)
|
||||
)
|
||||
|
||||
result = await HstSHBackend().async_create_paste(
|
||||
GenericFile(stderr.decode())
|
||||
)
|
||||
return await ctx.edit(
|
||||
embed=discord.Embed(
|
||||
title="Nmap failed.",
|
||||
description=f"Output was too long. [View full output]({result.url})",
|
||||
color=discord.Color.red()
|
||||
)
|
||||
)
|
||||
await ctx.edit(
|
||||
embed=discord.Embed(
|
||||
title="Nmap finished!",
|
||||
description="Result files are attached.\n"
|
||||
"* `gnmap` is 'greppable'\n"
|
||||
"* `xml` is XML output\n"
|
||||
"* `nmap` is normal output",
|
||||
color=discord.Color.green()
|
||||
),
|
||||
files=files
|
||||
)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(NetworkCog(bot))
|
||||
|
|
Loading…
Reference in a new issue