2024年全国大学生信息安全竞赛安徽省赛(线下初赛)-本科组WP
REVERSE
是 java 吗

是一个归档文件;
了解一下.jar文件:

可以直接打开:

得到如上图的一个界面,有一个触发按钮:

注册器的题目(一般flag形式比较明显本题:XXXX-XXXX-XXXX-XXXX),先随便输入几个测试信息,预估流程。

大概就就是想使用此产品必须支付。
这里需要用到JD-GUI
打开(定位到关键部分):

这里就是执行主要操作的步骤:
定位到关键语句:Well done that was the correct key
上面由于是反汇编,不一定能够与源码保持一致,这里只是稍微难看了一点,正常的理解就好:
str=input;
跟踪一下判断的注册码正确的函数:

从这里可以判断出flag的位数为19位,也就是注册码,其中数据部分就是索引的16位数据;
一个判断语段;有一个数据对比,分别是input与原始数据对比;
这里有一个迷惑的点,注意绕开arraycopy():这里不是Java中的方法,注意所属类,
这里就是需要获取原有的数据,按照比对的顺序输出即可得到破解注册器的注册码;
注意乱码处:
跟进arraycopy():

这里与参数无关,返回值来自Star的main()函数:

这里有一串特殊字符: vȾ¤ÊÊ¬ÆÆÊv̤ʲʲÀΤ¨¸¬
转换成为字符串数组进行左移1,加15的操作;得到ªı的数据
之后回到对比处:跟进₪₪₪₪₪₪₪₪₪₪₪₪()函数

这里就是索引的返回值,索引的值在ªı中。
破案,上脚本:

flag{sssn-trtk-tcea-akJr}
宝贝
输入长度38, 先逐字节与下标加1异或, 然后取[5:37]先异或0x30, 再异或[0x73, 0x63, 0x74, 0x66][(i-5) % 4].
f = open("data","rb")
data = f.read()
f.close()
code = ""
for i in xrange(0, len(data)):
v = ord(data[i])
vv = 0
# flip bits
for j in xrange(0, 8):
k = v & (1 << j)
k >>= j
k <<= 7-j
vv |= k
code+=chr(vv)
f = open("code","wb")
f.write(code)
f.close()
flag解密脚本:
# byte_412038
a = \
[
0x72, 0x61, 0x77, 0x62, 0x7E, 0x07, 0x35, 0x2E,
0x26, 0x24, 0x31, 0x38, 0x28, 0x12, 0x35, 0x07,
0x18, 0x22, 0x2F, 0x0F, 0x26, 0x34, 0x71, 0x25,
0x10, 0x20, 0x27, 0x37, 0x24, 0x32, 0x23, 0x0B,
0x18, 0x0E, 0x1F, 0x0F, 0x52, 0x5B
]
for i in xrange(0, 38):
a[i] ^= i+1
for i in xrange(5, 37):
a[i] ^= 0x30
for i in xrange(5, 37):
a[i] ^= [0x73, 0x63, 0x74, 0x66][(i-5) % 4]
flag=""
for i in xrange(0, 38):
flag+=chr(a[i])
print flag
sctf{Babymips_iS_so_ea5y_yoooooooooo!}
CRYPTO
Rsa 相关
线性相关攻击
from gmpy2 import *
from libnum import *
n=51296885372346449295388453471330409021784141081351581975478435681552082076338697136130122011636685327781785488670769096434920591920054441921039812310126089859349902066456998315283909435249794317277620588552441456327265553018986591779396701680997794937951231970194353001576159809798153970829987274504038146741
a=13256631249970000274738888132534852767685499642889351632072622194777502848070957827974250425805779856662241409663031192870528911932663995606616763982320967
b=12614470377409090738391280373352373943201882741276992121990944593827605866548572392808272414120477304486154096358852845785437999246453926812759725932442170
c1=18617698095122597355752178584860764221736156139844401400942959000560180868595058572264330257490645079792321778926462300410653970722619332098601515399526245808718518153518824404167374361098424325296872587362792839831578589407441739040578339310283844080111189381106274103089079702496168766831316853664552253142
c2=14091361528414093900688440242152327115109256507133728799758289918462970724109343410464537203689727409590796472177295835710571700501895484300979622506298961999001641059179449655629481072402234965831697915939034769804437452528921599125823412464950939837343822566667533463393026895985173157447434429906021792720
def attack(c1, c2, a, b, e, n):
PR.<x>=PolynomialRing(Zmod(n))
g1 = x^e - c1
g2 = (a*x + b)^e - c2
def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()
print(gcd(g1, g2))
return -gcd(g1, g2)[0]
m1 = attack(c1, c2, a, b, 17, n)
flag = n2s(int(m1))
print(flag)
rwx
通过代码的分析得知 rwx 分别对应了flag每个字符二进制的后三位,e是去掉了后三位,确定好范围,就可以进行爆破,爆破exp
z = z.split()
b=b.split()
a=a.split()
re=[]
for g in b:
for r in range(0,2):
for w in range(0,2):
for x in range(0,2):
for c in a:
rwx='{}{}{}'.format(r,w,x)
tmp=bytes.fromhex(c)
d=(long_to_bytes(int(bin(bytes_to_long(tmp))[2:]+rwx,2)))
e=hashlib.sha256(d).hexdigest()
if e==g:
re.append(rwx)
print(len(z))
ee=[]
for m in z:
for i in range(0,31):
for j in range(0,255):
for k in range(0,255):
h=(str(i)).encode()+bytes([j,k])
p=hashlib.sha256(h).hexdigest()
if p==m:
ee.append(i)
print(ee)
for i in range(len(re)):
x=int(bin(ee[i])+re[i][::-1],2)
print(chr(x),end='')
music
偷懒
Rsa 共享素数gcd求p直接正常解rsa
def rsa_gcd(c1,c2,n1,n2,e):
p=gcd(n1,n2)
q=n1//p
return rsa_decrypt(c1,e,p,q)
MISC
KISS ME
直接把图片放到工具里发现存在lsb色道隐写

发现有个二维码,直接扫描二维码得到flag
flag{i love u}
图像损坏
找一个正常GIF 文件的头补上,拆gif的帧拆除

对映base64码表,对映的位置的数字字母,写出来之后解base64
CTF{abc_def_g}
补全吧
添加头89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
添加尾AE 42 60 82
然后改宽高

