Skip to content
Closed
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8d5f302
File named hostcheck.py is added to check whether target is buggy or…
Aarush289 Oct 24, 2025
aa994c5
Update app.py
Aarush289 Oct 24, 2025
ed7c81e
Update hostcheck.py , removed unnecessary logs
Aarush289 Oct 24, 2025
ccd870e
Updated hostcheck.py to use allow_single_label and return the lower-c…
Aarush289 Oct 24, 2025
b5da801
Docstring added
Aarush289 Oct 24, 2025
c1a9201
app.py updated to remove noise in exception handling
Aarush289 Oct 24, 2025
b66a598
Multi-threading issue is resolved
Aarush289 Oct 24, 2025
949c911
chore: test signed commit (SSH)
Aarush289 Oct 24, 2025
50374b9
chore: test signed commit (SSH) #2
Aarush289 Oct 24, 2025
2389890
chore: test signed commit (SSH) #3
Aarush289 Oct 24, 2025
859b850
Merge branch 'master' into feature/my-change
Aarush289 Oct 25, 2025
a83c17f
Removed unnecessary print statements
Aarush289 Oct 25, 2025
d852609
Indentation done
Aarush289 Oct 25, 2025
4de4cca
trim dot before checking the length
Aarush289 Oct 25, 2025
c472e71
Update hostcheck.py
Aarush289 Oct 25, 2025
fb43add
Logging exceptions for better debugging
Aarush289 Oct 25, 2025
8102395
Hostcheck.py OS-independent; add validate_before_scan
Aarush289 Oct 27, 2025
cd4e5ab
Hostchecker is made OS independent and validate_before_scan is adde…
Aarush289 Oct 27, 2025
c92c7f3
Update hostcheck.py to make it OS independent
Aarush289 Oct 27, 2025
8752881
Indentation done
Aarush289 Oct 27, 2025
bd762cd
removed the duplicate key
Aarush289 Oct 27, 2025
c23507e
unused parameter removed
Aarush289 Oct 27, 2025
7de608e
"Fix import order (ruff E402), isort formatting; run pre-commit"
Aarush289 Oct 27, 2025
87b773c
Per-pass timeout added
Aarush289 Oct 27, 2025
0ac3a96
Deadline removed
Aarush289 Oct 27, 2025
8565db6
Indentation done
Aarush289 Oct 27, 2025
ec97266
Suggested changes are done
Aarush289 Oct 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ results.*
coverage.xml

venv
Public_sign
Public_sign.pub
cks_proxy
1 change: 1 addition & 0 deletions nettacker/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class DefaultSettings(ConfigBase):
show_all_profiles = False
show_help_menu = False
show_version = False
validate_before_scan = False
skip_service_discovery = False
socks_proxy = None
targets = None
Expand Down
65 changes: 62 additions & 3 deletions nettacker/core/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from threading import Thread

import multiprocess

from concurrent.futures import ThreadPoolExecutor, as_completed
from nettacker import logger
from nettacker.config import Config, version_info
from nettacker.core.arg_parser import ArgParser
Expand All @@ -23,6 +23,7 @@
is_ipv6_range,
is_ipv6_cidr,
)
from nettacker.core.hostcheck import resolve_quick, is_ip_literal, valid_hostname
from nettacker.core.messages import messages as _
from nettacker.core.module import Module
from nettacker.core.socks_proxy import set_socks_proxy
Expand Down Expand Up @@ -142,7 +143,7 @@ def expand_targets(self, scan_id):
):
targets += generate_ip_range(target)
# domains probably
else:
else:
targets.append(target)
self.arguments.targets = targets
self.arguments.url_base_path = base_path
Expand Down Expand Up @@ -220,7 +221,6 @@ def run(self):
if self.arguments.scan_compare_id is not None:
create_compare_report(self.arguments, scan_id)
log.info("ScanID: {0} ".format(scan_id) + _("done"))

return exit_code

def start_scan(self, scan_id):
Expand Down Expand Up @@ -289,7 +289,66 @@ def scan_target(

return os.EX_OK


def filter_valid_targets(self, targets, timeout_per_target=2.0, max_workers=None, dedupe=True):
"""
Parallel validation of targets via resolve_quick(target, timeout_sec).
Returns a list of canonical targets (order preserved, invalids removed).
"""
# Ensure it's a concrete list (len, indexing OK)
try:
targets = list(targets)
except TypeError:
raise TypeError(f"`targets` must be iterable, got {type(targets).__name__}")

if not targets:
return []

if max_workers is None:
max_workers = min(len(targets), 10) # cap threads

# Preserve order
canon_by_index = [None] * len(targets)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The names can be clearer


def _task(idx, t):
ok, canon = resolve_quick(t, timeout_sec=timeout_per_target)
return idx, t, (canon if ok and canon else None)

with ThreadPoolExecutor(max_workers=max_workers) as ex:
futures = [ex.submit(_task, i, t) for i, t in enumerate(targets)]
for fut in as_completed(futures):
try:
idx, orig_target, canon = fut.result()
except (OSError, socket.gaierror) as exc:
log.debug(f"Invalid target (resolver error): {exc!s}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logger doesn't have a .debug() method. Change this to .error().

continue

if canon:
canon_by_index[idx] = canon
else:
log.info(f"Invalid target -> dropping: {orig_target}")

# Keep order, drop Nones
filtered = [c for c in canon_by_index if c is not None]

if dedupe:
seen, unique = set(), []
for c in filtered:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider better names, if iterator is not being used elsewhere then just use an "_"

if c not in seen:
seen.add(c)
unique.append(c)
return unique
return filtered

def scan_target_group(self, targets, scan_id, process_number):

if(not self.arguments.socks_proxy and self.arguments.validate_before_scan):
targets = self.filter_valid_targets(
targets,
timeout_per_target=2.0,
max_workers=self.arguments.parallel_module_scan or None,
dedupe=True,
)
active_threads = []
log.verbose_event_info(_("single_process_started").format(process_number))
total_number_of_modules = len(targets) * len(self.arguments.selected_modules)
Expand Down
9 changes: 9 additions & 0 deletions nettacker/core/arg_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,15 @@ def add_arguments(self):
dest="skip_service_discovery",
help=_("skip_service_discovery"),
)
method_options.add_argument(
"-C",
"--validate-before-scan",
action="store_true",
default=Config.settings.validate_before_scan,
dest="validate_before_scan",
help=_("validate_before_scan"),

)
method_options.add_argument(
"-t",
"--thread-per-host",
Expand Down
123 changes: 123 additions & 0 deletions nettacker/core/hostcheck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# nettacker/core/hostcheck.py
from __future__ import annotations
import re
import socket
import time
import concurrent.futures
import os
import sys
from nettacker import logger
from nettacker.core.ip import (
get_ip_range,
generate_ip_range,
is_single_ipv4,
is_ipv4_range,
is_ipv4_cidr,
is_single_ipv6,
is_ipv6_range,
is_ipv6_cidr,
)
log = logger.get_logger()

_LABEL = re.compile(r"^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$")

def is_ip_literal(name: str) -> bool:
"""Return True if name is a valid IPv4 or IPv6 address literal."""
try:
socket.inet_pton(socket.AF_INET, name)
return True
except OSError:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exceptions are slower than if-else statements. You're better off with precompiling an IPv4 regex (IPv6 would be too complex) at least and not relying on a try-except block as part of the main execution flow.

pass
try:
socket.inet_pton(socket.AF_INET6, name)
return True
except OSError:
return False

def valid_hostname(
host: str,
allow_single_label: bool = True
) -> bool:
"""
Validate hostname syntax per RFC 1123.
Args:
host: Hostname to validate.
allow_single_label: If True, accept single-label names (e.g., "localhost").
Returns:
True if the hostname is syntactically valid.
"""
if host.endswith("."):
host = host[:-1]
if len(host) > 253:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do add a comment here to specify this comes from RFC1123 which specifies the number of characters to be 250 at max (without dots) and 253 with dots.

return False
parts = host.split(".")
if len(parts) < 2 and not allow_single_label:
return False
return all(_LABEL.match(p) for p in parts)


def _gai_once(name: str, use_ai_addrconfig: bool, port):
flags = getattr(socket, "AI_ADDRCONFIG", 0) if use_ai_addrconfig else 0
return socket.getaddrinfo(
name, port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, flags
)

def _clean_host(s: str) -> str:
# remove surrounding quotes and whitespace, lone commas, repeated dots
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you handling repeated dots?

s = s.strip().strip('"').strip("'")
s = s.strip() # again, after quote strip
# drop trailing commas that often sneak in from CSV-like inputs
if s.endswith(","):
s = s[:-1].rstrip()
# collapse accidental spaces inside
return s

def resolve_quick(
host: str,
timeout_sec: float = 2.0,
allow_single_label: bool = True
) -> tuple[bool, str | None]:
"""
Perform fast DNS resolution with timeout.
Args:
host: Hostname or IP literal to resolve.
timeout_sec: Maximum time to wait for resolution.
allow_single_label: If True, allow single-label hostnames (e.g., "intranet").
Returns:
(True, host_name) on success, (False, None) on failure/timeout.
"""
host = _clean_host(host)
if is_single_ipv4(host) or is_single_ipv6(host):
if is_ip_literal(host):
return True, host
return False, None

if host.endswith("."):
host = host[:-1]

if not valid_hostname(host):
return False, None

if "." not in host and not allow_single_label:
return False, None

def _call(use_ai_addrconfig: bool):
return _gai_once(host, use_ai_addrconfig, None)

for use_ai in (True, False):
try:
# Run getaddrinfo in a thread so we can enforce timeout
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as ex:
fut = ex.submit(_call, use_ai)
fut.result(timeout=timeout_sec) # raises on timeout or error
return True, host.lower()
except concurrent.futures.TimeoutError:
continue
except (OSError, socket.gaierror):
# DNS resolution failed for this candidate, try next
continue
return False, None


1 change: 1 addition & 0 deletions nettacker/locale/ar.yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to translate for all. Just en.yaml is enough, we'll leave the translations to the native speakers.

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ username_from_file: قراءة اسم المستخدم (ق) من الملف
password_separator: كلمة (كلمات) المرور ، منفصلة مع "،"
read_passwords: قراءة كلمة (كلمات) من الملف
port_separator: قائمة port (s) ، منفصلة مع "،"
validate_before_scan: تحقق مسبقًا من الأهداف/الاتصال قبل الفحص؛ سيتم تخطي الأهداف غير القابلة للوصول
time_to_sleep: وقت للنوم بين كل طلب
error_target: لا يمكن تحديد الهدف (الأهداف)
error_target_file: "لا يمكن تحديد الهدف (الأهداف) ، غير قادر على فتح الملف: {0}"
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/bn.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ connection_retries: সংযোগ সময়সীমা (ডিফল্ট
current_version: আপনি কোড নাম {3}{4}{5} সহ OWASP Nettacker সংস্করণ {0}{1}{2}{6} চালাচ্ছেন
database_connect_fail: ডাটাবেস সংযোগ করতে পারে না!
database_connection_failed: সংযোগ নির্বাচিত ডাটাবেস থেকে ব্যর্থ হয়েছে
validate_before_scan: স্ক্যানের আগে টার্গেট/কানেক্টিভিটি প্রি-ভ্যালিডেট করুন; যেগুলো পৌঁছানো যায় না সেগুলো বাদ দেওয়া হবে
define_white_list: "হোয়াইট লিস্ট হোস্টকে সংজ্ঞায়িত করুন, এটি আলাদা করুন, (উদাহরণ: 127.0.0.1, 1 9 2.168.0.1/24, 10.0.0.1-10.0.0.255 )"
engine: ইঞ্জিন
filtered_content: ... [রিপোর্টে পূর্ণ সামগ্রী দেখুন]
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ target_input: Zieleingabeoptionen
target_list: Ziel (e) Liste, getrennt mit ","
read_target: Lese Ziel (e) aus Datei
scan_method_options: Scan-Methodenoptionen
validate_before_scan: "Ziele/Konnektivität vor dem Scan vorvalidieren; nicht erreichbare Ziele werden übersprungen."
choose_scan_method: Suchmethode {0} auswählen
exclude_scan_method: Suchmethode auswählen, um {0} auszuschließen
username_list: Benutzername (s) Liste, getrennt mit ","
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/el.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ target_input: Επιλογές εισαγωγής στόχων
target_list: λίστα στόχων, χωριστά με ","
read_target: να διαβάσετε τους στόχους από το αρχείο
scan_method_options: Επιλογές μεθόδου σάρωσης
validate_before_scan: Προέλεγχος στόχων/συνδεσιμότητας πριν από τη σάρωση· οι μη προσβάσιμοι στόχοι παραλείπονται
choose_scan_method: επιλέξτε τη μέθοδο σάρωσης {0}
exclude_scan_method: επιλέξτε μέθοδο σάρωσης για να εξαιρέσετε {0}
username_list: όνομα χρήστη (ες), χωριστά με ","
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ API_options: API options
API_port: API port number
Method: Method
skip_service_discovery: skip service discovery before scan and enforce all modules to scan anyway
validate_before_scan: Pre-validate targets/connectivity before scanning; unreachable targets are skipped.
no_live_service_found: no any live service found to scan.
icmp_need_root_access: to use icmp_scan module or --ping-before-scan you need to run the script as root!
available_graph: "build a graph of all activities and information, you must use HTML output. available graphs: {0}"
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/es.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ scan_method_options: Opciones de método de escaneo
choose_scan_method: elija el método de escaneo {0}
exclude_scan_method: elija el método de escaneo para excluir {0}
username_list: nombre de usuario (s) list, separe con ","
validate_before_scan: Prevalidar objetivos/conectividad antes de escanear; los objetivos inaccesibles se omiten
username_from_file: leer nombre (s) de usuario del archivo
password_separator: lista de contraseña (s), separe con ","
read_passwords: leer contraseña (s) del archivo
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/fa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ target_list: لیست هدف (ها)، با "," جدا کنید
read_target: خواندن هدف (ها) از فایل
scan_method_options: گزینه های متود های اسکن
choose_scan_method: متود اسکن را انتخاب کنید {0}
validate_before_scan: قبل از اسکن، هدف‌ها/اتصال بررسی اولیه شوند؛ هدف‌های غیرقابل دسترس نادیده گرفته می‌شوند
exclude_scan_method: انتخاب متود اسکن استثنا {0}
username_list: لیست نام کاربری (ها)، با "," جدا شود
username_from_file: خواندن نام کاربری (ها) از لیست
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/fr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ choose_scan_method: choisissez la méthode de scan {0}
exclude_scan_method: choisissez la méthode de scan pour exclure {0}
username_list: nom d'utilisateur (s), séparé par ","
username_from_file: lire le (s) nom (s) d'utilisateur à partir du fichier
validate_before_scan: Pré-valider les cibles/la connectivité avant l’analyse ; les cibles injoignables sont ignorées
password_separator: mot de passe (s), séparé par ","
read_passwords: lire le (s) mot de passe (s) du fichier
port_separator: port (s) list, séparé par ","
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/hi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ password_separator: पासवर्ड (ओं) सूची, "," से अ
read_passwords: फ़ाइल से पासवर्ड पढ़ें
port_separator: पोर्ट (ओं) सूची, "," से अलग
time_to_sleep: प्रत्येक अनुरोध के बीच रुकने के लिए समय
validate_before_scan: स्कैन से पहले टार्गेट/कनेक्टिविटी का प्री-वैलिडेशन करें; जो टार्गेट पहुँच में नहीं हैं उन्हें छोड़ दिया जाएगा
error_target: लक्ष्य निर्दिष्ट नहीं कर सकते
error_target_file:
"फ़ाइल को खोलने में असमर्थ, लक्ष्य (लक्ष्य) निर्दिष्ट नहीं कर सकते:
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/hy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ username_from_file: կարդացեք օգտվողի անունը (ներ) ը ֆ
password_separator: գաղտնաբառերի ցուցակը, որը առանձին է «,»
read_passwords: կարդալ գաղտնաբառ (ներ) ը ֆայլից
port_separator: պորտ (ներ) ցուցակը, որը առանձին է «,»
validate_before_scan: Սքանավորումից առաջ նախաստուգել թիրախները/կապը; անհասանելի թիրախները կբաց թողնվեն։
time_to_sleep: յուրաքանչյուր խնդրի միջեւ քնելու ժամանակ
error_target: Հնարավոր չէ նշել թիրախ (ներ)
error_target_file: Հնարավոր չէ նշել թիրախ (ներ) ը, չի կարող բացել ֆայլը, {0}
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/id.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ password_separator: daftar kata sandi, terpisah dengan ","
read_passwords: baca kata sandi (s) dari file
port_separator: daftar port (s), terpisah dengan ","
time_to_sleep: waktu untuk tidur di antara setiap permintaan
validate_before_scan: Pra-validasi target/konektivitas sebelum pemindaian; target yang tidak dapat dijangkau akan dilewati
error_target: Tidak dapat menentukan target (s)
error_target_file: "Tidak dapat menentukan target (s), tidak dapat membuka file: {0}"
thread_number_warning:
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/it.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ username_from_file: "leggi username (s) dal file"
password_separator: lista password (s), separare con ","
read_passwords: "leggere password (s) dal file"
port_separator: elenco port (s), separare con ","
validate_before_scan: "Pre-convalidare target/connettività prima della scansione; i target non raggiungibili vengono ignorati"
time_to_sleep: "tempo di dormire tra ogni richiesta"
error_target: "Non è possibile specificare il / i target / i"
error_target_file: "Impossibile specificare il / i target / i, impossibile aprire il file: {0}"
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/iw.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ time_to_sleep: זמן לישון בין כל בקשה
error_target: לא ניתן להגדיר את המיקודים
error_target_file: "לא ניתן לציין את היעדים, לא ניתן לפתוח את הקובץ: {0}"
thread_number_warning: עדיף להשתמש במספר פתיל נמוך מ -100, BTW אנחנו ממשיכים ...
validate_before_scan: אמת מראש יעדים/קישוריות לפני הסריקה; יעדים שאינם נגישים ידולגו.
settimeout: להגדיר פסק זמן ל {0} שניות, זה גדול מדי, לא? בדרך שאנחנו ממשיכים ...
scan_module_not_found: מודול הסריקה [{0}] לא נמצא!
error_exclude_all: לא ניתן לבצע אי הכללה של כל שיטות הסריקה
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/ja.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ read_passwords: ファイルからパスワードを読み込む
port_separator: ポートリスト、 "、"
time_to_sleep: 各リクエストの間にスリープする時間
error_target: ターゲットを指定できません
validate_before_scan: スキャン前にターゲット/接続性を事前検証します。到達不能なターゲットはスキップされます。
error_target_file: ファイルを開くことができないターゲットを指定することはできません:{0}
thread_number_warning: 100より低いスレッド番号を使用する方が良いです、私たちは継続しています...
settimeout: タイムアウトを{0}秒に設定すると大きすぎますね。私たちが続けているところで...
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/ko.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ port_separator: 포트 목록, ","
time_to_sleep: 각 요청 사이에 잠자기 시간
error_target: 타겟을 지정할 수 없습니다.
error_target_file: "파일을 열 수없는 대상을 지정할 수 없습니다 : {0}"
validate_before_scan: 스캔 전에 대상/연결성을 사전 검증합니다. 도달 불가능한 대상은 건너뜁니다.
thread_number_warning: 100보다 낮은 스레드 번호를 사용하는 것이 좋습니다. 계속 진행 중입니다 ...
settimeout: 시간 초과를 {0} 초로 설정하면 너무 큽니다. 그렇지 않습니까? 그런데 우리가 계속 ...
scan_module_not_found: 이 스캔 모듈 [{0}]을 찾을 수 없습니다!
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/nl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ read_passwords: lees wachtwoord (s) uit bestand
port_separator: poort (en) lijst, gescheiden door ","
time_to_sleep: tijd om te slapen tussen elk verzoek
error_target: Kan het doel (de doelen) niet specificeren
validate_before_scan: Targets/verbinding vooraf valideren vóór de scan; onbereikbare targets worden overgeslagen
error_target_file: "Kan doel (en) niet specificeren, kan bestand niet openen: {0}"
thread_number_warning:
het is beter om een ​​draadnummer lager dan 100 te gebruiken,
Expand Down
1 change: 1 addition & 0 deletions nettacker/locale/ps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ username_list: د کارن نوموونکي لیست، د "،" سره جلا
username_from_file: د دوتنې څخه کارن نوم
password_separator: د پټنوم (لسټ) لیست، د "،" سره جلا کړئ
read_passwords: د دوتنې څخه پټنوم (پوسټ) ولولئ
validate_before_scan: له سکان مخکې هدفونه/نښلول مخکې له مخکې تایید کړئ؛ ناہرسايل هدفونه پرېښودل کېږي
port_separator: د بندرونو لیست، د "،" سره جلا کول
time_to_sleep: د هرې غوښتنې په منځ کې د خوب کولو وخت
error_target: هدف یا هدف مشخص کولی نشی
Expand Down
Loading