Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: auto correct url based on poc's protocol attribute #316

Merged
merged 3 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 14 additions & 1 deletion pocsuite3/lib/core/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,21 @@ class POC_CATEGORY:
PROTOCOL.HTTP = "Http"
PROTOCOL.FTP = "Ftp"
PROTOCOL.SSH = "Ssh"
PROTOCOL.TELENT = "Telent"
PROTOCOL.TELNET = "Telnet"
PROTOCOL.REDIS = "Redis"
PROTOCOL.SMTP = 'SMTP'
PROTOCOL.DNS = 'DNS'
PROTOCOL.SNMP = 'SNMP'
PROTOCOL.SMB = 'SMB'
PROTOCOL.MQTT = 'MQTT'
PROTOCOL.MYSQL = 'MySQL'
PROTOCOL.RDP = 'RDP'
PROTOCOL.UPNP = 'UPnP'
PROTOCOL.AJP = 'AJP'
PROTOCOL.XMPP = 'XMPP'
PROTOCOL.WINBOX = 'Winbox'
PROTOCOL.MEMCACHED = 'Memcached'
PROTOCOL.BACNET = 'BACnet'


class OPTION_TYPE:
Expand Down
5 changes: 1 addition & 4 deletions pocsuite3/lib/core/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,7 @@ def _attack_mode(self, mod):
rhost = self.current_module.getg_option("rhost")
rport = self.current_module.getg_option("rport")
ssl = self.current_module.getg_option("ssl")
scheme = "http"
if ssl:
scheme = "https"
target = "{scheme}://{rhost}:{rport}".format(scheme=scheme, rhost=rhost, rport=rport)
target = f"https://{rhost}:{rport}" if ssl else f"{rhost}:{rport}"
conf.mode = mod
kb.task_queue.put((target, self.current_module))
try:
Expand Down
53 changes: 47 additions & 6 deletions pocsuite3/lib/core/poc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from collections import OrderedDict

from requests.exceptions import ConnectTimeout, ConnectionError, HTTPError, TooManyRedirects
from pocsuite3.lib.core.common import parse_target_url, mosaic, check_port, OrderedSet, get_host_ip
from pocsuite3.lib.core.common import mosaic, check_port, OrderedSet, get_host_ip
from pocsuite3.lib.core.data import conf, logger
from pocsuite3.lib.core.enums import OUTPUT_STATUS, CUSTOM_LOGGING, ERROR_TYPE_ID, POC_CATEGORY
from pocsuite3.lib.core.exception import PocsuiteValidationException
Expand Down Expand Up @@ -164,13 +164,50 @@ def check_requirement(self, *args):
return True

def build_url(self):
target = parse_target_url(self.target)
target = self.target
# https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
protocol_default_port_map = {
POC_CATEGORY.PROTOCOL.FTP: 21,
POC_CATEGORY.PROTOCOL.SSH: 22,
POC_CATEGORY.PROTOCOL.TELNET: 23,
POC_CATEGORY.PROTOCOL.REDIS: 6379,
POC_CATEGORY.PROTOCOL.SMTP: 25,
POC_CATEGORY.PROTOCOL.DNS: 53,
POC_CATEGORY.PROTOCOL.SNMP: 161,
POC_CATEGORY.PROTOCOL.SMB: 445,
POC_CATEGORY.PROTOCOL.MQTT: 1883,
POC_CATEGORY.PROTOCOL.MYSQL: 3306,
POC_CATEGORY.PROTOCOL.RDP: 3389,
POC_CATEGORY.PROTOCOL.UPNP: 1900,
POC_CATEGORY.PROTOCOL.AJP: 8009,
POC_CATEGORY.PROTOCOL.XMPP: 5222,
POC_CATEGORY.PROTOCOL.WINBOX: 8291,
POC_CATEGORY.PROTOCOL.MEMCACHED: 11211,
POC_CATEGORY.PROTOCOL.BACNET: 47808
}

try:
pr = urlparse(target)
self.scheme = 'https' if pr.scheme.startswith('https') else 'http'
self.scheme = pr.scheme
self.rhost = pr.hostname
self.rport = pr.port if pr.port else 443 if pr.scheme.startswith('https') else 80
self.rport = pr.port
self.netloc = pr.netloc

if self.current_protocol in protocol_default_port_map:
# adjust protocol
self.scheme = self.current_protocol.lower()
# adjust port
if not self.rport:
self.rport = protocol_default_port_map[self.current_protocol]
self.netloc = f'{self.rhost}:{self.rport}'
else:
if self.scheme not in ['http', 'https']:
self.scheme = 'https' if str(self.rport).endswith('443') else 'http'
self.rport = self.rport if self.rport else 443 if self.scheme.startswith('https') else 80
self.netloc = f'{self.rhost}:{self.rport}'
pr = pr._replace(scheme=self.scheme)
pr = pr._replace(netloc=self.netloc)
target = pr.geturl()
except ValueError:
pass
if self.target and self.current_protocol != POC_CATEGORY.PROTOCOL.HTTP and not conf.console_mode:
Expand All @@ -194,6 +231,8 @@ def _execute(self):
def execute(self, target, headers=None, params=None, mode='verify', verbose=True):
self.target = target
self.url = self.build_url()
if self.url != self.target:
logger.debug(f'auto correct url: {mosaic(self.target)} -> {mosaic(self.url)}')
# TODO: Thread safe problem in self.headers
# https://github.com/knownsec/pocsuite3/issues/262
# The value should not be modified in PoC Plugin !!!
Expand Down Expand Up @@ -277,6 +316,7 @@ def _check(self, dork='', allow_redirects=False, return_obj=False, is_http=True,
# https://www.zoomeye.org/searchResult?q=%22running%20in%20SSL%20mode.%20Try%22
'running in ssl mode. try'
]
origin_url = self.url
netloc = self.url.split('://', 1)[-1]
urls = OrderedSet()
urls.add(self.url)
Expand All @@ -291,13 +331,13 @@ def _check(self, dork='', allow_redirects=False, return_obj=False, is_http=True,
if k.lower() in res.text.lower():
self.url = f'https://{netloc}'
res = requests.get(self.url, allow_redirects=allow_redirects)
logger.warn(f'auto correct url to: {mosaic(self.url)}')
logger.warn(f'auto correct url: {mosaic(origin_url)} -> {mosaic(self.url)}')
corrected = True
break
# another protocol is access ok
if not corrected and url != self.url:
self.url = url
logger.warn(f'auto correct url to: {mosaic(self.url)}')
logger.warn(f'auto correct url: {mosaic(origin_url)} -> {mosaic(self.url)}')
break
except requests.RequestException:
pass
Expand All @@ -306,6 +346,7 @@ def _check(self, dork='', allow_redirects=False, return_obj=False, is_http=True,
self.scheme = 'https' if self.url.startswith('https') else 'http'
port = urlparse(self.url).port
self.rport = port if port else 443 if self.scheme.startswith('https') else 80
self.netloc = f'{self.rhost}:{self.rport}'

if return_obj:
return res
Expand Down
2 changes: 1 addition & 1 deletion pocsuite3/pocs/ftp_burst.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def parse_attack(self, result):


def get_word_list():
common_username = ('ftp', 'test', 'root', 'guest', 'admin', 'daemon', 'user')
common_username = ('admin', 'ftp', 'test', 'root', 'guest', 'daemon', 'user')
with open(paths.WEAK_PASS) as f:
return itertools.product(common_username, f)

Expand Down
2 changes: 1 addition & 1 deletion pocsuite3/pocs/telnet_burst.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DemoPOC(POCBase):
desc = '''telnet 存在弱密码,导致攻击者可登录主机进行恶意操作'''
samples = ['']
category = POC_CATEGORY.TOOLS.CRACK
protocol = POC_CATEGORY.PROTOCOL.TELENT
protocol = POC_CATEGORY.PROTOCOL.TELNET

def _verify(self):
result = {}
Expand Down