# 简单直接一些
之前python 调用DNSlog.cn 进行OOB外带验证,代码如下:
# headers 头部
dnslog_headers = {
"Host":"dnslog.cn",
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding":"gzip, deflate",
"Accept-Language":"zh-CN,zh;q=0.9",
"Cookie":"PHPSESSID=xxxxxxxxxxxx"
}
try:
# dnslog.cn 的ip地址为47.244.138.18
getdomain = requests.get(url='http://dnslog.cn/getdomain.php',headers=dnslog_headers, timeout=6)
dnslog_domain = str(getdomain.text)
# payload 位置
# dnslog刷新查看是否存在记录
time.sleep(2) # 受网络影响,等待2秒后再进行查询
for i in range(0, 5): # 多次刷新,
refresh = requests.get(url='http://dnslog.cn/getrecords.php', headers=dnslog_headers, timeout=60)
time.sleep(1)
if dnslog_domain in refresh.text:
return "OK"
except Exception as e:
logging.error(e)
发现的第一个问题,我们公司会把 dnslog.cn 解析成 127.0.0.1 ,离了大谱。把域名换成IP,用了一段时间,发现解析时间非常久,还会出现卡死的情况。
# 整改后的代码
选择了 Interactsh 作为后续的 DNSlog 外带查询。代码来自 Pocsuite3。
import string
import random
from uuid import UUID
import os
import time
import requests
import base64
import json
from base64 import b64encode
import logging
from Cryptodome.Cipher import AES, PKCS1_OAEP
from Cryptodome.Hash import SHA256
from Cryptodome.PublicKey import RSA
def uuid4():
"""Generate a random UUID."""
return UUID(bytes=os.urandom(16), version=4)
def random_str(length=10, chars=string.ascii_letters + string.digits):
return ''.join(random.sample(chars, length))
class Interactsh():
def __init__(self, server='', token=''):
rsa = RSA.generate(2048)
self.public_key = rsa.publickey().exportKey()
self.private_key = rsa.exportKey()
self.server = 'oast.fun'
self.token = token
# if 'oob_token' in conf:
# self.token = self.token or conf.oob_token
self.headers = {
"Content-Type": "application/json",
}
if self.token:
self.headers['Authorization'] = self.token
self.secret = str(uuid4())
self.encoded = b64encode(self.public_key).decode("utf8")
guid = uuid4().hex.ljust(33, 'a')
guid = ''.join(i if i.isdigit() else chr(ord(i) + random.randint(0, 20)) for i in guid)
self.domain = f'{guid}.{self.server}'
self.correlation_id = self.domain[:20]
self.session = requests.session()
self.session.headers = self.headers
self.register()
def register(self):
data = {
"public-key": self.encoded,
"secret-key": self.secret,
"correlation-id": self.correlation_id
}
msg = f"[PLUGIN] Interactsh: Can not initiate {self.server} DNS callback client"
try:
res = self.session.post(
f"http://{self.server}/register", headers=self.headers, json=data, verify=False)
if res.status_code == 401:
logging.error("[PLUGIN] Interactsh: auth error")
elif 'success' not in res.text:
logging.error(msg)
except requests.RequestException:
logging.error(msg)
def build_request(self, length=10, method='http'):
"""
Generate the url and flag for verification
:param length: The flag length
:param method: Request type (dns|https|http), the default is https
:return: dict { url: Return the request url, flag: Return a random flag }
Example:
{
'url': 'http://hqlbbwmo8u.7735s13s04hp4eu19s4q8n963n73jw6hr.interactsh.com',
'flag': 'hqlbbwmo8u'
}
"""
flag = random_str(length).lower()
url = f'{flag}.{self.domain}'
if method.startswith('http'):
url = f'{method}://{url}'
return url, flag
def poll(self):
count = 3
result = []
while count:
try:
url = f"http://{self.server}/poll?id={self.correlation_id}&secret={self.secret}"
res = self.session.get(url, headers=self.headers, verify=False).json()
aes_key, data_list = res['aes_key'], res['data']
for i in data_list:
decrypt_data = self.decrypt_data(aes_key, i)
result.append(decrypt_data)
return result
except Exception as e:
print("[PLUGIN] Interactsh: {}".format(e))
count -= 1
time.sleep(1)
continue
return []
def verify(self, flag, get_result=False):
"""
Check the flag
:param flag: The flag to verify
:param get_result: Whether to return detailed results
:return: Boolean
"""
result = self.poll()
for item in result:
if flag.lower() in item['full-id'].lower():
return (True, result) if get_result else True
return (False, result) if get_result else False
def decrypt_data(self, aes_key, data):
private_key = RSA.importKey(self.private_key)
cipher = PKCS1_OAEP.new(private_key, hashAlgo=SHA256)
aes_plain_key = cipher.decrypt(base64.b64decode(aes_key))
decode = base64.b64decode(data)
bs = AES.block_size
iv = decode[:bs]
cryptor = AES.new(key=aes_plain_key, mode=AES.MODE_CFB, IV=iv, segment_size=128)
plain_text = cryptor.decrypt(decode)
return json.loads(plain_text[16:])
oob = Interactsh(token="", server="")
url, flag = oob.build_request()
if verify(flag):
print("success")
原文始发于微信公众号(石头安全):记一次对OOB的白嫖
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论