Skip to content

Commit

Permalink
Merge branch 'darkoperator:master' into feature_add_domain_list_flag
Browse files Browse the repository at this point in the history
  • Loading branch information
McFacePunch authored Oct 20, 2024
2 parents b0c6c1e + bb0b189 commit 9e03fd5
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 48 deletions.
17 changes: 13 additions & 4 deletions dnsrecon/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

__version__ = '1.3.0'
__author__ = 'Carlos Perez, [email protected]'
__name__ = 'cli.py'
__name__ = 'cli'

__doc__ = """
DNSRecon https://www.darkoperator.com
Expand Down Expand Up @@ -1499,9 +1499,6 @@ def ds_zone_walk(res, domain, lifetime):


def main():
logger.remove()
logger.add(sys.stderr, format='{time} {level} {message}', level='DEBUG')
logger.add('~/.config/dnsrecon/dnsrecon.log', rotation='100 MB', compression='tar.gz')
#
# Option Variables
#
Expand Down Expand Up @@ -1611,6 +1608,15 @@ def main():
default=3.0,
help='Time to wait for a server to respond to a query. default is 3.0',
)

parser.add_argument(
'--loglevel',
type=str,
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
default='INFO',
help='Log level to use. default is INFO',
)

parser.add_argument(
'--tcp',
dest='tcp',
Expand Down Expand Up @@ -1669,6 +1675,9 @@ def main():
zonewalk: Perform a DNSSEC zone walk using NSEC records.""",
)
arguments = parser.parse_args()
logger.remove()
logger.add(sys.stderr, format='{time} {level} {message}', level=arguments.loglevel)
logger.add('~/.config/dnsrecon/dnsrecon.log', rotation='100 MB', compression='tar.gz')

except SystemExit:
# Handle exit() from passing --help
Expand Down
4 changes: 3 additions & 1 deletion dnsrecon/lib/crtenum.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ def scrape_crtsh(dom):
Function for enumerating subdomains by scraping crt.sh.
"""
results = []
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.3'}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.3'
}
url = f'https://crt.sh/?q=%25.{dom}'

req = Request(url=url, headers=headers)
Expand Down
113 changes: 70 additions & 43 deletions tests/test_dnsrecon.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,71 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Unit test for DNSRecon main functions
# Author: Filippo Lauria (@filippolauria)
#
# Copyright (C) 2021 Carlos Perez
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; Applies version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from unittest.mock import patch, MagicMock
from dnsrecon import cli
from dnsrecon.lib.dnshelper import DnsHelper
import os


class Test_dnsrecon():

def test_in_cache(self):
namelist_filename = 'namelist.tmp'
namelist = ['localhost', 'test', 'www', 'mail']
with open(namelist_filename, 'w') as fd:
fd.writelines([f"{name}\n" for name in namelist])
helper = DnsHelper('zonetransfer.me')
ns = '81.4.108.41'
result = cli.in_cache(helper, namelist_filename, ns)
os.remove(namelist_filename)
assert len(result) == 1 and result[0]['type'] == 'A'

def test_se_result_process(self):
helper = DnsHelper('zonetransfer.me')
hosts = ['www.megacorpone.com', 'www.zonetransfer.me']
result = cli.se_result_process(helper, hosts)
assert len(result) >= 2


def test_check_wildcard():
with patch('dnsrecon.lib.dnshelper.DnsHelper') as mock_dns_helper:
mock_instance = mock_dns_helper.return_value
mock_instance.check_wildcard.return_value = (True, ["192.0.2.1"])
result = cli.check_wildcard(mock_instance, "zonetransfer.me")
assert result == set() # The function returns an empty set


def test_expand_range():
input_range = "192.0.2.0"
end_ip = "192.0.2.3"
result = cli.expand_range(input_range, end_ip)
assert len(result) == 4
assert "192.0.2.0" in result
assert "192.0.2.3" in result


def test_brute_domain():
with patch('dnsrecon.lib.dnshelper.DnsHelper') as mock_dns_helper, \
patch('builtins.input', return_value='y'): # Mock user input
mock_instance = mock_dns_helper.return_value
mock_instance.get_a.return_value = ["192.0.2.1"]
mock_instance.get_aaaa.return_value = ["2001:db8::1"]
mock_instance.check_wildcard.return_value = (False, [])

# Mock the generate_testname function to return a valid string
with patch('dnsrecon.cli.generate_testname', return_value='testname.zonetransfer.me'):
result = cli.brute_domain(mock_instance, "zonetransfer.me", ["subdomain"])

assert isinstance(result, list)


def test_general_enum():
with patch('dnsrecon.lib.dnshelper.DnsHelper') as mock_dns_helper:
mock_instance = mock_dns_helper.return_value
mock_instance.get_a.return_value = ["192.0.2.1"]
mock_instance.get_aaaa.return_value = ["2001:db8::1"]
mock_instance.get_mx.return_value = ["mail.zonetransfer.me"]
mock_instance.get_txt.return_value = ["txt.zonetransfer.me"]
mock_instance.get_ns.return_value = ["ns.zonetransfer.me"]
mock_instance.get_soa.return_value = ["soa.zonetransfer.me"]
mock_instance.get_srv.return_value = ["srv.zonetransfer.me"]
mock_instance.get_spf.return_value = ["spf.zonetransfer.me"]
mock_instance.get_nsec.return_value = ["nsec.zonetransfer.me"]
mock_instance.get_nsec3.return_value = ["nsec3.zonetransfer.me"]
mock_instance.get_nsec3param.return_value = ["nsec3param.zonetransfer.me"]
mock_instance.get_ds.return_value = ["ds.zonetransfer.me"]
mock_instance.get_dnskey.return_value = ["dnskey.zonetransfer.me"]
mock_instance.get_rrsig.return_value = ["rrsig.zonetransfer.me"]
result = cli.general_enum(mock_instance, "zonetransfer.me", True, True, True, True, True, True, True, 5.0)
assert result is None # The function doesn't return anything


def test_get_nsec_type():
with patch('dnsrecon.lib.dnshelper.DnsHelper') as mock_dns_helper:
mock_instance = mock_dns_helper.return_value
mock_instance._res = MagicMock()
mock_instance._res.nameservers = ["8.8.8.8"]
mock_instance._res.timeout = 2.0

mock_answer = MagicMock()
mock_answer.authority = []

with patch('dnsrecon.cli.get_a_answer', return_value=mock_answer):
result = cli.get_nsec_type("zonetransfer.me", mock_instance)

assert result is None

0 comments on commit 9e03fd5

Please sign in to comment.