原神怎么你了!|

eth258

园龄:1年9个月粉丝:0关注:0

第八届西湖论剑 cscs

并不是完全复现,后面cs1.6不想看
第一次做cs的流量,记录下复现。其实官wp讲的清楚过头了,我写都不知道干嘛

第八届西湖论剑·中国杭州网络安全技能大赛初赛官方Write Up(下)

奇安信攻防社区-Cobaltstrike4.0 学习——http分阶段stagebeacon上线流量刨根问底

看看http对象,很明显的cs特征

mB9u

ascii对应十进制,然后求和对256取余,最后余数和92、93来对比,92是x86,93是x64

stringss="mB9u"
num=0
for cha in stringss:
    num=num+ord(cha)

data=num%256
#data=93 就是x64的beacon

然后就跟着submit.php?id=这个默认配置的特征

image-20250224155307804

具体cs流量流程是这样子的,这里不做太多描述,官p够看了

图片

那现在需要私钥来解密cookies中的命令执行以及响应包中的data

看wp,可以知道

常规的cobalt strike流量题目,一般都会给出用于rsa解密的私钥,cobalt strike中加密cookie的公钥私钥文件存在于一个叫做.cobaltstrike.beacon_keys的文件,这个文件是在cobalt strike中新增监听器的时候生成的,是一个java序列化格式的文件,里面存在着一个java的KeyPair对象,其中的内容便是一对公钥私钥

图片

图片

但是这里什么都没给

那么如何获取解密过程中第一步的rsa公私钥呢?在这段流量中,给出了cobalt strike木马上线时所发送的stage文件,我们首先导出这个stage文件

这里补充到能拿私钥的两种方式(看最开始给的第二个链接文章)

从这篇文章我们可以知道两种方法,一个是用默认私钥梭哈,第二个就是dump stage来分析

image-20250224161333517

用到了这个脚本来分析stage

https://github.com/minhangxiaohui/CSthing/blob/master/1768_v0_0_8/1768.py

image-20250224162040928

取出公钥,wp说后续的0是不需要的,公钥通常是质数,确实不应该是0结尾

30819e300d06092a864886f70d010101050003818c00308188028180525e1781f2f02d132a7818a6d269baddbf39352c8d20290ec2294fbe4d77e6549ef4766d8b0e1620000adfbd7aff99cd72f05623eb0def202265cf631dd895acd5e981da8424c03a295895c8194a31641f2eecd5a8715ca89cdbf9433c5d437538767666c3bdb0f8629555375b574fe408a94ae82f92960085d416374f1654b30203010001

知道公钥后提取其中的公钥指数e和模数n

from Crypto.PublicKey import RSA
import binascii

# 将你的16进制字符串放在这里
hex_key = "30819e300d06092a864886f70d010101050003818c00308188028180525e1781f2f02d132a7818a6d269baddbf39352c8d20290ec2294fbe4d77e6549ef4766d8b0e1620000adfbd7aff99cd72f05623eb0def202265cf631dd895acd5e981da8424c03a295895c8194a31641f2eecd5a8715ca89cdbf9433c5d437538767666c3bdb0f8629555375b574fe408a94ae82f92960085d416374f1654b30203010001"  # 用你的实际十六进制字符串替换
# 将十六进制字符串转换为字节
key_bytes = binascii.unhexlify(hex_key)
# 导入RSA公钥
rsa_key = RSA.import_key(key_bytes)
# 提取模数(n)和指数(e)
n = rsa_key.n
e = rsa_key.e
# 打印模数和指数
print(f"Modulus (n): {n}")
print(f"Exponent (e): {e}")

# 将RSA公钥导出为PEM格式
pem_key = rsa_key.publickey().export_key(format='PEM')
# 打印PEM格式公钥
print(pem_key.decode('utf-8'))
Modulus (n): 57840457943390562151183056895981922848981888713417943532946260250633760347281370187050725047626507035739078370095883411759062129893337622945780596526859424702568086671495882125464325172299346781795855931036288858784790023273356190549125683636953077021666004867856782395818167722491980517593426129106599564467
Exponent (e): 65537
-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFJeF4Hy8C0TKngYptJput2/OTUs
jSApDsIpT75Nd+ZUnvR2bYsOFiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHa
hCTAOilYlcgZSjFkHy7s1ahxXKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUro
L5KWAIXUFjdPFlSzAgMBAAE=
-----END PUBLIC KEY-----

但是https://factordb.com/并没有收录这个模数n,只能自己爆

image-20250224164452222

知道p q n e 求d就简单了

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.utils import (
       encode_dss_signature,
       decode_dss_signature,
   )
from cryptography.hazmat.backends import default_backend
import gmpy2
from sympy import nextprime, isprime
import random


def generate_rsa_keys_from_components(p, q, n, e, d):
    """
    使用提供的 n, e, d 生成 RSA 密钥对
    :param n: 模数 (int)
    :param e: 公钥指数 (int)
    :param d: 私钥指数 (int)
    :return: 公钥和私钥对象
    """
    private_key = rsa.RSAPrivateNumbers(
        p=p,
        q=q,
        d=d,
        dmp1=d % (p - 1),
        dmq1=d % (q - 1),
        iqmp=rsa.rsa_crt_iqmp(p, q),
        public_numbers=rsa.RSAPublicNumbers(e=e, n=n),
    ).private_key(backend=default_backend())

    public_key = private_key.public_key()

    return public_key, private_key


def save_keys_to_pem(public_key, private_key, public_path, private_path):
    """
    将公钥和私钥保存为 PEM 格式的文件
    :param public_key: 公钥对象
    :param private_key: 私钥对象
    :param public_path: 公钥文件路径
    :param private_path: 私钥文件路径
    """
    public_pem = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo,
    )

    private_pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption(),
    )

    with open(public_path, "wb") as f:
        f.write(public_pem)

    with open(private_path, "wb") as f:
        f.write(private_pem)



def main():
       p = 7605291443685150594150190909345113655196508809219162555499789316232908573154196070425269090153291952292016936024761413150455793038505322748933150548026221
       q = 7605291443685150594150190909345113655196508809219162555499789316232908573154196070425269090153291952292016936024761413150455793038505322748933150548026527
       e = 0x10001
       n = p * q
       phi = (p - 1) * (q - 1)
       d = gmpy2.invert(e, phi)
       print(d)
       d = int(d)
# 生成密钥对
       public_key, private_key = generate_rsa_keys_from_components(p, q, n, e, d)
# 保存密钥到文件
       save_keys_to_pem(public_key, private_key, "publicKey.pem", "privateKey.pem")
       print("公钥和私钥已成功生成并保存到文件中!")
if __name__ == "__main__":
       main()

后面就不仿照官p了,用以下脚本解密即可

CSthing/cs-decrypt-metadata_V0_0_1/cs-decrypt-metadata.py at master · minhangxiaohui/CSthing

用法

将私钥的值base64解密再转hex

 python .\cs-decrypt-metadata.py -p 私钥 密文
>python .\cs-decrypt-metadata.py -p 30820274020100300d06092a864886f70d01010105000482025e3082025a020100028180525e1781f2f02d132a7818a6d269baddbf39352c8d20290ec2294fbe4d77e6549ef4766d8b0e1620000adfbd7aff99cd72f05623eb0def202265cf631dd895acd5e981da8424c03a295895c8194a31641f2eecd5a8715ca89cdbf9433c5d437538767666c3bdb0f8629555375b574fe408a94ae82f92960085d416374f1654b3020301000102818029595aebbd8d9cd3364abbf56343f8af4143f2d1beb71a65724b52e0f1faf302201a1129c4d8f97a6f0b066f14c423ede3798b84d4875638078c9ca3e163cd1f392830b3abd2ae2ec27319cc504127dc0330e184b00486811a474b9dfc5fa5b4bf91451bff3eff035491b4dab59f88596229e71b636952e88ed56ab01ea386a10241009135e3e555b7c38d188675a887f872a027026b689cf8720cd7586500b4225c4dcf28b1a3f96795373cd1bde3614038c3c18641065e6bbd28a784527c8255e36d0241009135e3e555b7c38d188675a887f872a027026b689cf8720cd7586500b4225c4dcf28b1a3f96795373cd1bde3614038c3c18641065e6bbd28a784527c8255e49f02407abc942e29efb368354ca1729bcb1207f031095c59215e352067e4a75d9a956e67253c511ee3c0a9f9cc46b644632617c0219c20a7fa64de520974372d6b2f590240219437ae09c363ea15d8ca0e7ddadb0ee3d67066119e762938070ddc3acb9352beebe720470548012d044787f42e38b233e74ad4213382db8ad95385cd51f57b024022a447ef9977f845a24b948a1665efd790d5e919cb1821e69e754bf6f71a9a3406c0ec7844b37b70bbaf86d103f562e00f369dbc14da1ee765df2615564f0d43 SLHAIOj8/1icVtP6fImtJz6B6wR0t/XwLg1G0Y3AxoxnseBfPONxoyjAWCCOH84IJULnCZZrO7cIRxJPS2PtmDD4MvD8/PIpoW8Gj8536vhwd+tyXjNKyLNyNYcj+JgO4N5FTnKtkONgv7KnsMjJC3E0eI0ctqmZll8SrXLUS9k=
Encrypted metadata: SLHAIOj8/1icVtP6fImtJz6B6wR0t/XwLg1G0Y3AxoxnseBfPONxoyjAWCCOH84IJULnCZZrO7cIRxJPS2PtmDD4MvD8/PIpoW8Gj8536vhwd+tyXjNKyLNyNYcj+JgO4N5FTnKtkONgv7KnsMjJC3E0eI0ctqmZll8SrXLUS9k=
Decrypted:
Header: 0000beef
Datasize: 0000005d
Raw key:  28ab951fc96bcb93ec13cf9dd5f21373
 aeskey:  9fe14473479a283821241e2af78017e8
 hmackey: 1e3d54f1b9f0e106773a59b7c379a89d
charset: 03a8 ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)
charset_oem: 03a8 ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)
bid: 4350dfec 1129373676
pid: 0b50 2896
port: 0
flags: 0e
var1: 6
var2: 1
var3: 7600
var4: 0
var5: 1996621008
var6: 1996633200
var7: 2360912064
Field: b'WIN-RRI9T9SN85D'
Field: b'Administrator'
Field: b'artifact.exe'

拿到AES_KEY、HMAC_KEY后可以直接用以下这个脚本来解密数据,往encrypt_data填入加密数据,就能解密数据

import hmac
import binascii
import base64
import hexdump
from Crypto.Cipher import AES

AES_KEY = binascii.unhexlify("9fe14473479a283821241e2af78017e8")
HMAC_KEY = binascii.unhexlify("1e3d54f1b9f0e106773a59b7c379a89d")
encrypt_data = "2861dcee3abe0beb543a42a83f765f8e8447799da043820c2fa534f47ef86e84bcb75dbab2b13772c66626d9461b64dffbd222ab8cb6098675785d68a054580a"
def decrypt(encrypted_data, iv_bytes, signature, AES_KEY, hmac_key):
    cipher = AES.new(AES_KEY, AES.MODE_CBC, iv_bytes)
    return cipher.decrypt(encrypted_data)

encrypt_data = bytes.fromhex(encrypt_data)

try:
    encrypt_data_length = int.from_bytes(encrypt_data[:4], byteorder='big', signed=False)
    encrypt_data_l = encrypt_data[4:]
    data1 = encrypt_data_l[:encrypt_data_length-16]
    signature = encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
    iv_bytes = b"abcdefghijklmnop"
    dec = decrypt(data1, iv_bytes, signature, AES_KEY, HMAC_KEY)
except:
    dec = decrypt(encrypt_data, iv_bytes, signature, AES_KEY, HMAC_KEY)

print("counter: {}".format(int.from_bytes(dec[:4], byteorder='big', signed=False)))
print("任务返回长度: {}".format(int.from_bytes(dec[4:8], byteorder='big', signed=False)))
print("任务输出类型: {}".format(int.from_bytes(dec[8:12], byteorder='big', signed=False)))
print(dec[12:int.from_bytes(dec[4:8], byteorder='big', signed=False)])
print(hexdump.hexdump(dec))

image-20250224203744831

后面就不看了

posted @   eth258  阅读(14)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起