2024春节红包题

cypto-01-signin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import *
from secret import flag


def gen(nbits: int):
p, q = [getPrime(nbits) for _ in range(2)]
e, n = 0x10001, p*q
d = inverse(e, n-p-q+1)
return (e, n), (d, p, q)


pk, sk = gen(nbits=256)
e, n = pk
enc = [pow(ch, e, n) for ch in flag]
print(f"{pk = }\n{enc = }")

对flag每个字符进行加密,实际上单个字符完全可以直接爆破。

1
2
3
4
5
6
7
8
9
10
11
from Crypto.Util.number import *
import string
pk = (65537, 11355675220005431104031869299277776757033070984975465951397916338422431969293215749949820817377468631904184187013014958573724152666442140455030774240024459)
enc = [3644889223722494066470481467815883098030922482945331019144701952471158908145031713993128627464507344932212297134636336366091355344710658047208354768026955, 8601716539839961462275851363366620020596972071259224371473391037385822347453883622345351985268374384880935466901191843895571432827072274183963301289172528, 147492636284951458980720766439111095694654351477825022649990169493566613097763450737541424090135047272251998445872224322262782134915431098063068412201273, 6499927684793518983296554072918504547569077169839399587901250533671657376501724647839787826301002082811386105830747038035542551963116909179753294483725899, 11210388194610675815502812258891358698353360797176712910352240522798006144053607172736575316508564595288936222464315530493478786357010948337255030598057497, 5390992427470134953244498417431625427960849801700725332916004542750778586471306015526129429479778086952985029288654462865041970960939870625721202439124689, 9497349303956505348231175455379266203695379388388698345595232013595558072350917001826018768477320231932815454140676866721629107520036646038419514557900205, 8601716539839961462275851363366620020596972071259224371473391037385822347453883622345351985268374384880935466901191843895571432827072274183963301289172528, 4807490159379587694451679670123655140022227086524951570857290712156225611371495031760571145225904883031359636009811183826012608209406685462091309705830387, 5239654056965367720305690763498461754857035230326918641198136972971010020395168810940997950345887712591335964753759537051187599638236498547203280450368097, 756879996662558211335855876184475562270503794542822006353055477637211280958437344529190441116279184609740941576087901711541343711471032450806001092584433, 9497349303956505348231175455379266203695379388388698345595232013595558072350917001826018768477320231932815454140676866721629107520036646038419514557900205, 9712424207049741358083618955531166680559298039651029205427815249165522482944303620957929304592081927615283448191421698137611510802275005564886105614670631, 9427163818233648192594600857435779445685690030091973637061974680210076259128697103075866873491880821134677648373845218404096437311934581345257307223544942, 7329404860572055729893862456969177057937405127012829507377529200729504664626533000195632337134531785426764679849701751855271794254723225288198630915204960, 9427163818233648192594600857435779445685690030091973637061974680210076259128697103075866873491880821134677648373845218404096437311934581345257307223544942, 2447155292214149297284185018865547553665446497190526187817168906201570537180498999566309939513028679091894570371421205391903841678267444119874203521282601, 9712424207049741358083618955531166680559298039651029205427815249165522482944303620957929304592081927615283448191421698137611510802275005564886105614670631, 1585080484333545422104251005290104822859874491469485956559223801419455994224176285629794238603096006225579890091476527747433824594703663674412244929292106, 4532303949072471510483211026493642516860807408505854460514141807814501284350744762241377083495501125891408104119091192574838849877292242502215901803395294, 7379615533596760709020251691248103700744607709588299362815088140044594719560556806799209861393875176193226849845415114924415483917927869035283104194909556]

s=string.printable
for i in range(len(enc)):
for j in s:
if pow(ord(j),pk[0],pk[1])==enc[i]:
print(j,end="")
break

misc-01-easypic

解压出来个png,010打开看一下文件头有点问题,前两个字符调换就好了
image.png
运行了下模板后发现IEND后面还有多余字符,开头是03 04,猜测是zip文件
image.png
image.png
补上文件头后发现有密码。

misc-02-recovery

image.png
用Passware能直接移除加密卷的密码
image.png
然后用DiskGenius打开解密后的加密卷,提取出DZ10.zip
image.png
伪加密,修改一下标识符
image.png
得到secret.txt
image.png

web-01-easyweb

php死亡绕过
image.png
$a前面的那部分内容使用某种手段(编码等)进行处理,导致php不能识别该部分
c=PD9waHAgZXZhbCgkX1BPU1RbYV0pOw==&file=php://filter/convert.base64-decode/resource=654321.php

re-02-MineSweeper

image.png
查壳 发现是Confuser.Core 1.6.0+447341964f
是没见过的东西 找个教学视频跟着走:https://www.youtube.com/watch?v=1BK588BjyBI

image.png
搜索gchandle.Free()下断点,右键保存koi。

关闭程序,打开koi.exe
image.png
可以看到壳已经去了,还剩confuserex的混淆
视频里还有一些别的保护机制,但这道题没有,所以可以直接跳到倒数第二步,拿ConfuserEx-Unpacker-v2.0解混淆。
image.png
image.png
最后我们使用de4dot 来恢复变量名称。
image.pngimage.png
现在代码逻辑就十分清晰明了了。跟着method_6一步一步还原函数就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import base64
def method_8(byte_2,string_2):
byte_0 = bytearray(range(256))
byte_1 = bytearray([ord(char) for char in string_2 * (256 // len(string_2)) + string_2[:256 % len(string_2)]])
num = 0
for j in range(256):
num = (num + byte_0[j] + byte_1[j]) % 256
method_9(byte_0, j, num)
num = 0
num2 = 0
num3 = len(byte_2)
array = bytearray(num3)
for i in range(num3):
num = (num + 1) % 256
num2 = (num2 + byte_0[num]) % 256
method_9(byte_0, num, num2)
b = (byte_0[num] + byte_0[num2]) % 256
array[i] = byte_2[i] ^ byte_0[b]
return array

def method_9(byte_2, int_4, int_5):
b = byte_2[int_4]
byte_2[int_4] = byte_2[int_5]
byte_2[int_5] = b

string_1='3EYivbN5BfW0nXVZtqYZWPvQMeNC'
string_2='500'
array = base64.b64decode(string_1)
string_2 = method_8(array,string_2)
print(string_2)
# bytearray(b'flag{H4ppy_New_Ye4r!}')

re-03-MVP

image.png
image.png
开ce玩出来了 hint说得对 确实能玩

cypto-02-math1

翻资料的时候翻到知乎上这么个问题:https://www.zhihu.com/question/30972581
image.png
扩展一下就是k进制下的数和它的各数位之和的模(k-1)相同

现在就是解下面的同余方程组

{m2708822338169559670811875583383402815 (mod 181243785594001721637839735699391269538)m173335656337921906425327063100295072221 (mod 285351613859281232825157091039873642030)m260290506483208164432954904890459214653 (mod 279913904804583316473011165356771247376)m216344747116637637973759547705226176739 (mod 333761953675945671612920291350810429098)\begin{cases} m \equiv 2708822338169559670811875583383402815\ ({\rm mod}\ 181243785594001721637839735699391269538) \\ m\equiv 173335656337921906425327063100295072221\ ({\rm mod}\ 285351613859281232825157091039873642030) \\ m \equiv 260290506483208164432954904890459214653\ ({\rm mod}\ 279913904804583316473011165356771247376)\\ m \equiv 216344747116637637973759547705226176739\ ({\rm mod}\ 333761953675945671612920291350810429098)\end{cases}

洛谷上找了个能用的扩展中国剩余定理的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from functools import reduce
from Crypto.Util.number import long_to_bytes

def gcd(a, b):
if b==0: return a
return gcd(b, a%b)

def lcm(a, b):
return a * b // gcd(a,b)

def exgcd(a, b):
if b==0: return 1, 0
x, y = exgcd(b, a%b)
return y, x - a//b*y

def uni(P, Q):
r1, m1 = P
r2, m2 = Q

d = gcd(m1, m2)
assert (r2-r1) % d == 0

l1, l2 = exgcd(m1//d, m2//d)

return (r1 + (r2-r1)//d*l1*m1) % lcm(m1, m2), lcm(m1, m2)

def CRT(eq):
return reduce(uni, eq)

if __name__ == "__main__":
eq = [[2708822338169559670811875583383402815, 181243785594001721637839735699391269538], [173335656337921906425327063100295072221, 285351613859281232825157091039873642030], [260290506483208164432954904890459214653, 279913904804583316473011165356771247376], [216344747116637637973759547705226176739, 333761953675945671612920291350810429098]]
print(long_to_bytes(CRT(eq)[0]))
#b'flag{math1-wish-you-good-luck}'

2024春节红包题
http://example.com/2024/02/29/JSMSA_CTF 2024年春节红包题/
作者
pjx1314
发布于
2024年2月29日
许可协议