第四届网鼎杯白虎组解密思路总结

2024-11-15 13 0

昨天白虎组的比赛刚刚结束,题目难度还是一如既往的难以言尽,本次分享一下解题思路和分析过程,从细小之处抽丝剥茧拿到flag。

MISC(杂项)

misc1

题目描述:

某5G研发单位接到5G系统瘫痪的告警,研究人员将其收发的流量进行监控,发现异常的报文,请对其分析。找到全部异常报文,将恶意报文中攻击者构造的teid按时间先后顺序进行拼接,找到全部由攻击者触发的异常报文进行拼接,所得出的拼接结果即为最终nag,例如,若按时间先后顺序排列的恶意报文中攻击者构造的teid“分别为0001​和0002​,则最终的fag值为'wdfag{00010002}~。

题目描述分析关键点:teid(这个是肯定要找到的);时间先后顺序,需要拼接且按照样例猜测是两个teid。

解题过程:

Wireshark打开UDF.cap,第一时间一眼很明显就能看到GTP(TCP)协议,不懂就GPT问,结果直接看到了参数包含了teid,这不就直接找到tied在哪了嘛。第四届网鼎杯白虎组解密思路总结插图第四届网鼎杯白虎组解密思路总结插图1​接下来就是过滤GTP协议的流量第四届网鼎杯白虎组解密思路总结插图2​看了一下还挺多的,所以这里需要用到tshark进行提取,先选中过滤一下第四届网鼎杯白虎组解密思路总结插图3​完了之后可以准确看到参数为gtp.teid,这个后面提取需要用到第四届网鼎杯白虎组解密思路总结插图4用tsahrk进行提取和分析,打开csv,可以看到这两条异常数据很明显,直接转成10进制,按照顺序进行拼接就是flag了。

tshark.exe -r UPF.cap -T fields -e gtp.teid > ted.csv

第四届网鼎杯白虎组解密思路总结插图5​这里就是进制转换之后的结果,拼接后就是flag了。第四届网鼎杯白虎组解密思路总结插图6​Misc2

题目描述:某通信运营商遭受到了攻击,但始终无法发现攻击过程,请你帮忙分析流量包,发现其中存在的问题。

题目分析关键点:这题没发现题目给啥提示,但是附件里面有一个encrypted.py的代码,所以结合题目说的无法发现攻击过程,猜测应该是流量加密了。关键就在这个encrypted.py的解密。

解题过程:

还是先打开GTP.cap流量包看看吧,发现全是GTP协议,而且数量也不多第四届网鼎杯白虎组解密思路总结插图7​追踪一下数据流,查看原始数据,确实是一串儿加密的,放gpt也不知道啥加密方式,流量分析就只能到这儿了。第四届网鼎杯白虎组解密思路总结插图8​转战看看encrypted.py脚本里面的加密方式,丢给了gpt进行了分析,发现是使用了ECB(电子密码本)模式的AES加密。

以下是加密脚本注释,方便大家直接看懂:

# 导入必要的模块  
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes  # 导入Cipher类以及AES算法和ECB模式  
from cryptography.hazmat.backends import default_backend  # 导入默认的后端  
import struct  # 导入struct模块,用于处理Python值与C结构体之间的转换  
  
# 定义一个填充函数,用于将明文填充到AES块大小的倍数(AES块大小为16字节)  
def pad(text):  
    # 使用空格字符将文本填充到长度是16的倍数  
    while len(text) % 16 != 0:  
        text += ' '  
    return text  
  
# 定义一个加密函数,接受密钥和明文作为输入  
def encrypt(key, plaintext):  
    # 将整数密钥转换为4字节的二进制数据,然后填充到16字节  
    key_bytes = struct.pack('>I', key)  # '>I'表示无符号大端整数(4字节)  
    key_bytes = key_bytes.ljust(16, b'\0')  # 使用空字节填充到16字节  
  
    # 创建一个Cipher对象,使用AES算法、ECB模式和默认后端  
    cipher = Cipher(algorithms.AES(key_bytes), modes.ECB(), backend=default_backend())  
  
    # 创建一个加密器对象  
    encryptor = cipher.encryptor()  
  
    # 对明文进行填充,然后编码为二进制数据  
    padded_plaintext = pad(plaintext).encode()  
  
    # 使用加密器对填充后的明文进行加密  
    # update方法用于处理输入数据,可能返回部分密文;finalize方法用于完成加密并返回剩余的密文  
    encrypted = encryptor.update(padded_plaintext) + encryptor.finalize()  
  
    # 返回加密后的密文  
    return encrypted  
  
# 主程序入口  
if __name__ == "__main__":  
    # 定义密钥和明文  
    key = 1  # 注意:这里使用整数1作为密钥,这在实践中是不安全的,因为密钥太短且缺乏随机性  
    msg = "123"  # 明文消息  
  
    # 调用加密函数并打印加密后的密文(以二进制形式表示)  
    print(encrypt(key, msg))

现在知道了加密方式以及密文,这里用的也是GTP协议,所以就猜测了密钥是teid,最后gpt辅助编写了以下解密脚本:

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import struct


def unpad(text):
    # 移除末尾的空格填充
    return text.rstrip(b' ')


def decrypt(key, ciphertext):
    # 将整数密钥转换为4字节的二进制数据,然后填充到16字节
    key_bytes = struct.pack('>I', key).ljust(16, b'\0')

    # 创建一个Cipher对象,使用AES算法、ECB模式和默认后端
    cipher = Cipher(algorithms.AES(key_bytes), modes.ECB(), backend=default_backend())

    # 创建一个解密器对象
    decryptor = cipher.decryptor()

    # 使用解密器对密文进行解密
    decrypted = decryptor.update(ciphertext) + decryptor.finalize()

    # 移除空格填充
    decrypted = unpad(decrypted)

    # 将解密后的二进制数据解码为字符串(如果原始明文是文本的话)
    # 注意:这里假设明文是UTF-8编码的文本,如果不是,请替换为正确的编码
    try:
        plaintext = decrypted.decode('utf-8')
    except UnicodeDecodeError:
        # 如果解密后的数据不是有效的UTF-8编码文本,则可能返回原始二进制数据
        # 或者根据需要处理错误(例如,记录日志、返回None等)
        plaintext = None  # 或者 return decrypted 直接返回二进制数据

    return plaintext


if __name__ == "__main__":
    key = 475070864
    ciphertext = bytes.fromhex(
        '4ff7909b1d1e3e1ef33dd958adf1f4fb25306274720f807c4252beaaa1fe31ad867ec46c1f48fa734de206574d3189f1')
    print(decrypt(key, ciphertext))

第四届网鼎杯白虎组解密思路总结插图9​Misc3

题目描述:某单位内网遭受攻击,请对提取到的网络流量数据进行分析。

题目分析:没有可用信息

解题过程:

先wireshark打开流量,追踪流看看,发现了攻击语句。​第四届网鼎杯白虎组解密思路总结插图10​一看是伪协议,多看两个包看看规律,发现全是伪协议,尝试着把这些伪协议进行提取看看

tshark.exe -r UPF.cap -T fields -e urlencoded-form.value > value.csv

第四届网鼎杯白虎组解密思路总结插图11​剩下的大家自己看吧,原理相似:https://www.ctfiot.com/142082.html

Misc4

题目描述:一天,某单位收到一个奇怪的文件,文件中的内容让人觉得存在安全隐患,于是你迅速联系我,邀请我同进行对文件进行分析。

题目分析:这道题没看出来啥

解题过程:

一共三个文件,打开第一个看看第四届网鼎杯白虎组解密思路总结插图12​发现有zip和png,这不就妥妥文件分离嘛,binwalk梭哈,两个压缩包,一个图片有半个flag,另一个压缩包有密码第四届网鼎杯白虎组解密思路总结插图13​看到这种情况,就两种可能:1、密码(试了不对) 2、掩码爆破第四届网鼎杯白虎组解密思路总结插图14​直接爆破掩码,密码出来了第四届网鼎杯白虎组解密思路总结插图15​解密后又是一张图片第四届网鼎杯白虎组解密思路总结插图16​图片的解法都是网上的老一套,先binwalk、formost啥的都试试,结果又分离出一张图片第四届网鼎杯白虎组解密思路总结插图17​遇到图片没啥好思路,不知道就所有解法用工具都淦一遍,乱拳打死老师傅。最后爆破宽高解出来了。第四届网鼎杯白虎组解密思路总结插图18​最后两段flag凑一凑就完整了

Crypt(密码学)

Crypt01

题目描述:小明是一名数学专业的学生,某一号师给他出了一道题,并在题目中隐藏了秘密,你能帮他解开题目吗?

解题过程:

实力不允许我解出这么高端的题目。

Crypt02

题目描述:小明说"我有量了计算机,你有吗?",你决定借他所谓的"量子计算机,"进行安全测试。

题目分析:只能从附件里面看出是rsa加密,pubkey.txt是解密需要用到的东西,另外一个应该是要解密的文件

解题过程:

分析源代码,可以看出是加密一个名为flag.txt​的文件。它首先生成了两个大素数p​和q​,然后计算它们的乘积N​作为模数,接着使用常见的公钥指数e = 65537​。最后,它将公钥(e​和N​)保存到pubkey.txt​文件中,并将加密后的消息保存到cipher.txt​文件中。

Tip:密码学的题目主要就跟大家在学校做数学题目一样。

整理一下已知条件:pubkey文件中已经有了e和N,加密文件是cipher.txt​

未知条件:p、q

# 导入必要的库函数  
from Crypto.Util.number import getPrime, isPrime  # 用于生成和检查素数  
  
# 定义密钥的位数  
nbits = 2048  # 总位数,用于生成p和q  
gbits = 1000  # 中间素数的位数,用于生成p和q的特殊形式  
  
# 生成一个中间素数g  
g = getPrime(int(gbits))  
  
# 生成第一个大素数p  
while True:  
    # 生成一个较小的素数a  
    a = getPrime(int(nbits * 0.5) - gbits)  
    # 根据特殊形式计算p  
    p = 2 * g * a + 1  
    # 检查p是否为素数  
    if isPrime(p):  
        break  # 如果是,则跳出循环  
  
# 生成第二个大素数q,过程与生成p类似,但要确保q != p  
while True:  
    b = getPrime(int(nbits * 0.5) - gbits)  # 生成另一个较小的素数b  
    q = 2 * g * b + 1  # 根据特殊形式计算q  
    # 检查q是否为素数且q != p  
    if p != q and isPrime(q):  
        break  # 如果是,则跳出循环  
  
# 计算模数N,它是p和q的乘积  
N = p * q  
  
# 定义公钥指数e  
e = 65537  # 常用的公钥指数值  
  
# 定义字符串与整数之间的转换函数  
def str2int(s):  
    # 将字符串编码为latin-1,然后转换为十六进制字符串,最后转换为整数  
    return int(s.encode('latin-1').hex(), 16)  
  
def int2str(i):  
    # 将整数转换为十六进制字符串,确保长度为偶数,然后解码为latin-1字符串  
    tmp = hex(i)[2:]  # 去除'0x'前缀  
    if len(tmp) % 2 == 1:  
        tmp = '0' + tmp  # 如果长度为奇数,则在前面补0  
    return bytes.fromhex(tmp).decode('latin-1')  # 转换为字节并解码为字符串  
  
# 保存公钥到文件  
with open('pubkey.txt', 'w') as f:  
    f.write(str(e) + '\n')  # 写入公钥指数e  
    f.write(str(N) + '\n')  # 写入模数N  
  
# 读取flag.txt文件并加密其内容  
with open('flag.txt') as f:  
    plain = str2int(f.read())  # 将文件内容转换为整数  
  
# 使用RSA加密算法加密明文  
c = pow(plain, e, N)  # 计算密文c = plain^e % N  
  
# 保存加密后的密文到文件  
with open('cipher.txt', 'wb') as f:  
    # 将密文转换为字符串并编码为latin-1,然后写入文件  
    f.write(int2str(c).encode('latin-1'))

RSA加密特点就是N=p*q,解密要素就是得找到p和q两个因素。

不太懂RSA加密核心思想的可以参考这篇文章:

https://jayxv.github.io/2019/11/11/%E5%AF%86%E7%A0%81%E5%AD%A6%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E4%B9%8B%E6%B5%85%E6%9E%90Pollard's%20rho%20algorithm%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8/

所以目前的首要目标是的想办法解出p和q,

p,q有了,pub文件中给65537

最后根据这三个,rsa解出txt,脚本是上面这个​wdflag{0b239acd8d741d855dfd1045258a5a6c2b188698690e54afa7a3dce08b62b942}​


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

webpack打包站点,js文件名批量获取思路
加密对抗靶场enctypt——labs通关
【论文速读】| 注意力是实现基于大语言模型的代码漏洞定位的关键
蓝队技术——Sysmon识别检测宏病毒
内网渗透学习|powershell上线cs
LLM attack中的API调用安全问题及靶场实践

发布评论