0x00 感受

第一次参加京东的CTF比赛吧,一人组队,题目偏简单,后2题没做(自己不太会逆向,工具使用不熟练,再加上工作忙没时间做了),不过自己后面还是会根据大佬WP复现一遍。

希望下一届能找到一群志同道合的朋天一起来玩比赛,从中还是能学到很多东西。

最后37名,惜败无法进入半决(前30名半决赛)。

0x01 题目一

题目

题目内容:欢迎加入“光之守卫”行动小组,请接受组织的考验吧?这是人类历史上第一款街机电子游戏,通过这关,您就能成为真正的光之守护计划的特工。

解法

两种解题思路:

  • 玩游戏

你打赢它6分就可以

  • 源码审计

image-20210826234647513

flag:JDCTF{my_first_computer_game}

0x02 题目二

题目

恭喜您,成功加入了“光之守护”行动小组,小组给各位准备了一份关于黑客组织的加密资料,需要您破解后才可查收,请解开这个4位密码吧。

image-20210826234848593

解法

从最左边的图形看出来向下箭头代表图形向下开口。右边8个上下一组,组成数字0259(自己画画图就出来了,类似于火柴字体)

[image-20210826235532310]

flag:0259

0x03 题目三

题目

仔细阅读了该组织的资料,你知道了它是一个专门针对供应链攻击的黑客组织。该组织近期给我司发来了一封名通过“栅栏加密”后的挑战书,上面写着:32 22 12 81 41 32 82 31。这一串数字不是电话号码,所以你推断一定是一个密码。这时候你看到自己电脑的键盘字母,发现了密码的规律。您能破解它吗?

解法

按照键盘把32 22 12 81 41 32 82 31转换出来,例如32表示第三列第二个。转换出来后是dsairdke。题中提示栅栏密码,在线栅栏解密,每组4个试了一下。

image-20210827000728592

这不是黑客组织darkside嘛🤭

flag:darkside

0x04 题目四

题目

解开了密码,您打开了挑战书,里面写着”你们以为你们足够了解我们吗?其实我们早已对“光之守卫”了如指掌,等着我们的挑战吧”。接着,你起身走向总部作战室的大门,希望仔细研究下后面的对策。到了门口,你发现忘带了钥匙,门上有一个电话按钮,上面有线索提示了4位密码,您能打开作战室的大门吗?

解法

答案4位密码,看了下74能拼出来拼音si,知道了是按照拼音做法,试着把所有情况都列了出来74是7/4,548是6/9,98是5,94是1。

排队组合一下一共4种: 7651,7951,4651,4951。一个试了试,最后答案是4651

flag:4651

0x05 题目五

题目

打开门后,我们进入了作战室,并发现了一台电脑,但您不知道开机密码是什么,这时候,您看到桌上有张图片,这个应该就是开机密码了。

解法

图片拼接,看着像有京和8,盲猜了一波京东618。猜对了。。至于图片拼接看了下需要旋转和镜像,挺麻烦的,这里不展示了,感兴趣可以自己试试。

0x06 题目六

题目

题目内容:打开作战室的电脑,电脑上面有个游戏,上面提示:请使用上下左右操作,让数字打到256会有惊喜,当然作为特工的您,早已发现更快速实现的方法。

解法

右键查看网页源码

有app.js,进一步查看.

发现flag

flag:JDCTF{i_am_not_2048}

0x07 题目七

题目

游戏通关了,您刚要冲杯咖啡,这时突然收到了darkside组织的一封署名为时光回溯的email,内容是“你们想知道我们的详细计划吗?时间的夹缝会给你们答案,我们已经把计划发到2004年京东网站上的一个email里,如果你们有能力玩这个游戏,那就先把这个email找出来”。

解法

题目说要2004年京东官网里一个email,所以要找2004年京东官网,使用互联网档案馆archive.org,2004年京东用的域名是360buy.com

查询04年最早时候7.7日的一份快照,进去查看。

查到结果jdren@jdlaser.com

flag:jdren@jdlaser.com

0x08 题目八

题目

题目内容:打开email,里面有一个京东的订单查询页,看起来好像很正常的样子,但是黑客组织不可能做没有意义的事情,里面肯定隐藏了什么阴谋。

解法

右键查看源码,发现存在JS fuck(代码混淆)写法。

直接复制出来在console里执行或者在在线JSFuck解密

flag:JDSEC{52ca7e26c3740802781441de10905e2f}

0x09 题目九

题目

果然,破解订单页之后,我收到了一条奇怪的消息,其中只有一串字符,他们想传达什么意思?SkRTRUN7UmVhMTF5X0Vhc3lfQ3J5cHQwfQ==

解法

base64加密,直接在线网站解密

flag:JDSEC{Rea11y_Easy_Crypt0}

0x0a 题目十

题目

解开字符,是一个标注为“星期六晚上7:30在北辰会面”,为了抢在他们之前阻止他们的阴谋,我迅速赶到北辰办公地点,发现了一台无人使用的电脑,但电脑需要开机密码。这时候我发现电脑桌上有一个便签,写着“让我们一起寻找宇宙奥秘”,解开这个问题或许有帮助。

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
flag = '???'

x = int(flag[6 : 23])
y = int(flag[23 : 40])
z = int(flag[40 : 57])

assert len(flag) == 58
assert flag[:6] == 'JDSEC{'
assert flag[57: 58] == '}'
assert x < y < z
assert x**3+y**3-z**3 == 42

解法

逻辑很清晰,flag的6-23位是x,23-40位是y,40-57位是z,flag长度58位,前6位JDSEC{,最后一位},而且x<y<z的

最重要是
$$
x^3+y^3-z^3 = 42
$$
网上搜了一下这个方程结果

最后拼接下所有条件得到flag

flag:JDSEC{126021232973356318043575814581751580538738812075974}

0x0b 题目十一

题目

解开便签拿到电脑密码,登陆进去我发现电脑当中有很多奇怪的文件,到底哪个是我们需要的文件呢?

下载下来是很多的bin(二进制)文件

解法

cat了一下很多空文件,猜测一个文件存在flag,直接cat *

flag:JDSEC{d4c31336acf0d32a3490ad6c65e650097cfc0}

0x0c 题目十二

题目

目标文件是一段代码风格十分糟糕的python,看来得把这个python调整过来。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
fdedefffbbdaegee = ord
beaffgfbffdeaeag = False
fgfcgchfcceegdgd = True
hfefddhaedfhacge = len
aebcbhfhhcggcfcd = 39
gcchfbgbchchhhfa = 28
fdbcabedabahgaaf = 8
fceheccbbebdbbca = 2
hdeagebfcghhgdeh = 25
aceaecbcdbgbdddb = 6
bfhbcecaeffbadab = 21
accdcabbbdcebehf = 17
ebdcecbffefgccde = 22
adeefecaefaggcfa = 32
hcbaddfgdhdbadca = 15
ebadhacgbggfbcab = 3
ecchbfgfbfcedheg = 18
bbhdeaafbeeedagh = 37
dedccbaegdbghdeg = 24
fadacffcbagdcffc = 1
dcbhbbcaedbgdcaf = 30
gfdfgeaedhchgdde = 7
ehagbceadagaefcf = 38
fehbhgfccfdheafh = 20
aacgfcaefacghaad = 33
ccafghdgffhdcgde = 34
fbhcdbhaefedafae = 5
agcaeheaffaehcef = 10
cchhbceheaeffece = 29
hdcfefebceacgbbg = 14
bdhggfaffchchacf = 4
hgafccfhghhbeehe = 31
hhhgcbagfdbagbfd = 12
ahbefgaaafhdecea = 27
dahghdbcfgedfehc = 11
ebfehfefaebbcdhe = 0
hggbbgggdhcddagd = 13
ddfahfchefhghbee = 19
ehdceghggeafcgbh = 23
feghfdhgccegghag = 9
facdaccedehaeghg = 35
ccagdhcahcdchbbc = 36
aggcfhehfdccadce = 26
ecbeagaadadagdba = 16

def aedfachbhhdgaabg(gaaagfedddhdcdcg):
if hfefddhaedfhacge(gaaagfedddhdcdcg) != aebcbhfhhcggcfcd:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[gcchfbgbchchhhfa]) != 48:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[fdbcabedabahgaaf]) != 57:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[fceheccbbebdbbca]) != 83:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[hdeagebfcghhgdeh]) != 53:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[aceaecbcdbgbdddb]) != 51:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[bfhbcecaeffbadab]) != 54:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[accdcabbbdcebehf]) != 56:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ebdcecbffefgccde]) != 99:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[adeefecaefaggcfa]) != 54:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[hcbaddfgdhdbadca]) != 99:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ebadhacgbggfbcab]) != 69:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ecchbfgfbfcedheg]) != 97:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[bbhdeaafbeeedagh]) != 97:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[dedccbaegdbghdeg]) != 48:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[fadacffcbagdcffc]) != 68:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[dcbhbbcaedbgdcaf]) != 52:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[gfdfgeaedhchgdde]) != 101:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ehagbceadagaefcf]) != 125:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[fehbhgfccfdheafh]) != 56:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[aacgfcaefacghaad]) != 50:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ccafghdgffhdcgde]) != 52:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[fbhcdbhaefedafae]) != 123:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[agcaeheaffaehcef]) != 52:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[cchhbceheaeffece]) != 52:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[hdcfefebceacgbbg]) != 97:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[bdhggfaffchchacf]) != 67:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[hgafccfhghhbeehe]) != 53:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[hhhgcbagfdbagbfd]) != 48:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ahbefgaaafhdecea]) != 97:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[dahghdbcfgedfehc]) != 52:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ebfehfefaebbcdhe]) != 74:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[hggbbgggdhcddagd]) != 101:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ddfahfchefhghbee]) != 99:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ehdceghggeafcgbh]) != 50:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[feghfdhgccegghag]) != 98:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[facdaccedehaeghg]) != 51:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ccagdhcahcdchbbc]) != 53:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[aggcfhehfdccadce]) != 50:
return beaffgfbffdeaeag
if fdedefffbbdaegee(gaaagfedddhdcdcg[ecbeagaadadagdba]) != 54:
return beaffgfbffdeaeag
return fgfcgchfcceegdgd

assert aedfachbhhdgaabg("your_flag")

解法

替换掉所有变量为数值

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
ord = ord
False = False
True = True
len = len
39 = 39
28 = 28
8 = 8
2 = 2
25 = 25
6 = 6
21 = 21
17 = 17
22 = 22
32 = 32
15 = 15
3 = 3
18 = 18
37 = 37
24 = 24
1 = 1
30 = 30
7 = 7
38 = 38
20 = 20
33 = 33
34 = 34
5 = 5
10 = 10
29 = 29
14 = 14
4 = 4
31 = 31
12 = 12
27 = 27
11 = 11
0 = 0
13 = 13
19 = 19
23 = 23
9 = 9
35 = 35
36 = 36
26 = 26
16 = 16

def function(flag):
if len(flag) != 39:
return False
if ord(flag[28]) != 48:
return False
if ord(flag[8]) != 57:
return False
if ord(flag[2]) != 83:
return False
if ord(flag[25]) != 53:
return False
if ord(flag[6]) != 51:
return False
if ord(flag[21]) != 54:
return False
if ord(flag[17]) != 56:
return False
if ord(flag[22]) != 99:
return False
if ord(flag[32]) != 54:
return False
if ord(flag[15]) != 99:
return False
if ord(flag[3]) != 69:
return False
if ord(flag[18]) != 97:
return False
if ord(flag[37]) != 97:
return False
if ord(flag[24]) != 48:
return False
if ord(flag[1]) != 68:
return False
if ord(flag[30]) != 52:
return False
if ord(flag[7]) != 101:
return False
if ord(flag[38]) != 125:
return False
if ord(flag[20]) != 56:
return False
if ord(flag[33]) != 50:
return False
if ord(flag[34]) != 52:
return False
if ord(flag[5]) != 123:
return False
if ord(flag[10]) != 52:
return False
if ord(flag[29]) != 52:
return False
if ord(flag[14]) != 97:
return False
if ord(flag[4]) != 67:
return False
if ord(flag[31]) != 53:
return False
if ord(flag[12]) != 48:
return False
if ord(flag[27]) != 97:
return False
if ord(flag[11]) != 52:
return False
if ord(flag[0]) != 74:
return False
if ord(flag[13]) != 101:
return False
if ord(flag[19]) != 99:
return False
if ord(flag[23]) != 50:
return False
if ord(flag[9]) != 98:
return False
if ord(flag[35]) != 51:
return False
if ord(flag[36]) != 53:
return False
if ord(flag[26]) != 50:
return False
if ord(flag[16]) != 54:
return False
return True

assert function("your_flag")

逻辑很清楚,flag长度以及每一位应该是那个字母,最后组装

[74,68,83,69,67,123,51,101,57,98,52,52,48,101,97,99,54,56,97,99,56,54,99,50,48,53,50,97,48,52,52,53,54,50,52,51,53,97,125]

自己python很差…. 都是现学的,所以转字符用Java写了

1
2
3
4
5
6
StringBuilder sb = new StringBuilder();
        int[] array =new int[]{74,68,83,69,67,123,51,101,57,98,52,52,48,101,97,99,54,56,97,99,56,54,99,50,48,53,50,97,48,52,52,53,54,50,52,51,53,97,125};
        for (int i = 0; i < array.length; i++) {
            sb.append((char)array[i]);
        }
        System.out.println(sb.toString());

Flag:JDSEC{3e9b440eac68ac86c2052a044562435a}

0x0d 题目十三

题目

python指引我去D盘找到了一个重要文件,但这个文件需要密码解开,文件名字是”rsa”。

两个文件一个是enc.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import os
from Crypto.Util import number

with open('../secret/flag', 'rb') as f:
flag = f.read()

assert(len(flag) < 200)
p = number.getPrime(1024)
q = number.getPrime(1024)
n = p * q
e = 65537

data = number.bytes_to_long(flag[:4])
flag = number.bytes_to_long(os.urandom(255-len(flag)) + flag)

with open('output.txt', 'w') as f:
print(n, file=f)
print(pow(flag, e, n), file=f)
print(pow(data, p, n), file=f)

一个是output.txt

1
2
3
16190071651163806295864019410478994111033069033627784225762863537603051286100205075670533295885064417368900028860200646693729094397336259104108103548185993908365388380839285172911963120514072321190266876940732034732397117137061394460746923843922245782775468266708629538795929791940224005947023797710889884139262655896037569495345277362100989310206818815906815037340109507090191392200724993896961774561625607045531746223966956306007588691156861073213545675831176519130019553724245771994149735589727939984664508149900746138671733567269193055682039733308565608623124419978622690108399287267782094992833491412117540060443
15303419998661114679314254717914026405478757825416735351601804954118839229797070479526681279224742375492655311505697019190557550696467480133256967636550925789855469334208787745973414205031434095712965892662629942032090010088494752811463912882633957119964067548777662273186260137022598527046219193475032906299912859488699286089311234866062127452250073707233182744079405190900962311612847001444141191413026226164120884637043140094140783528285331931332316785677352225990586242903100117563104312764791553556755518103356463537538508315396815826486784213208395270070213346386705111244580124327114520898478012805359398827670
1510184595792565064445440906881935995266619097536001461530783965780154369249043641074486895520464486085479962000078556210579654456510298579647913754227118673129421819393900310384823524058038067616709691791898230083313217906194886078501873907639225319148093330535005464365092684845804210054017334558737467574892102337630443813828900547064330664128905647113707379303375108854244133403877761359312330320014228059025076059037200823315174250296513866303939391915733284159144473793081857745772615093108270863280285078431940816859845225827381322898005915615672862823461308519156692000709906390303017977729854164511610194054

解法

RSA非对称加密题,做题你得先懂RSA,RSA原理详解

好了,看完RSA原理后看下这道题的情况,现在已知的有n, e, 和两段密文,还有data。这里的data特殊说明下,是通过猜测出来的,flag格式是JDSEC{flag},所以前4位是JDSE,所以data 也是已知的。现在通过公式推导。

$$
pow(data,p,n) => data^p \text{ % n} = output_3
$$
转换一下形式
$$
data^p - output_3 = kn
$$
两边同时对p求余
$$
(data^p - output_3) \text{ % p} = (kn) \text{ % p}
$$
因为n = p * q,所以kn % p = 0,那么data^p和output3余数应该是一样的
$$
data^p \text{ % p} = output_3 \text{ % p}
$$
使用费马小定理,如下转换
$$
\text {因为 } data^{p - 1} \equiv 1 \pmod p
$$

$$
data*data^{p - 1}\text{ % p} = output_3 \text{ % p}
$$

所以得出来
$$
data = output_3 \text{ % p}
$$
变换形式
$$
output_3 - data = kp
$$
又因为
$$
n = pq
$$
所以n和output3-data存在最大公约数p,通过gcd函数算出来最大公约数就是p,这样q也就知道了 同样的 (p-1)(q-1)也能求出来,这样就可以通过(p-1)(q-1)和e算出来私钥d,最后通过(n,d)解密密文。

下面是解密脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util import number
import math
import gmpy2
e = 65537
n = 16190071651163806295864019410478994111033069033627784225762863537603051286100205075670533295885064417368900028860200646693729094397336259104108103548185993908365388380839285172911963120514072321190266876940732034732397117137061394460746923843922245782775468266708629538795929791940224005947023797710889884139262655896037569495345277362100989310206818815906815037340109507090191392200724993896961774561625607045531746223966956306007588691156861073213545675831176519130019553724245771994149735589727939984664508149900746138671733567269193055682039733308565608623124419978622690108399287267782094992833491412117540060443
v = 1510184595792565064445440906881935995266619097536001461530783965780154369249043641074486895520464486085479962000078556210579654456510298579647913754227118673129421819393900310384823524058038067616709691791898230083313217906194886078501873907639225319148093330535005464365092684845804210054017334558737467574892102337630443813828900547064330664128905647113707379303375108854244133403877761359312330320014228059025076059037200823315174250296513866303939391915733284159144473793081857745772615093108270863280285078431940816859845225827381322898005915615672862823461308519156692000709906390303017977729854164511610194054
m = 15303419998661114679314254717914026405478757825416735351601804954118839229797070479526681279224742375492655311505697019190557550696467480133256967636550925789855469334208787745973414205031434095712965892662629942032090010088494752811463912882633957119964067548777662273186260137022598527046219193475032906299912859488699286089311234866062127452250073707233182744079405190900962311612847001444141191413026226164120884637043140094140783528285331931332316785677352225990586242903100117563104312764791553556755518103356463537538508315396815826486784213208395270070213346386705111244580124327114520898478012805359398827670
flag = 'JDSEC{}'
data = number.bytes_to_long(flag[:4].encode())
# v - data 和 n的最大公约数
p = math.gcd(n, v - data)
q = n // p
phi = (p - 1) * (q - 1)
# 求e的模反元素d
d = gmpy2.invert(e, phi)
# (n,d)私钥解密
real_flag = pow(m, d, n)
r = number.long_to_bytes(real_flag)
print(r)

flag:JDSEC{37439fdaba4c2d282a64a71a74d676d4dac412a78d9c183f80f018d19b1415d9}

0x0e 题目十四

题目

解开之后,我发现居然还有一个rsa密码,是双重加密文件,看来这个文件非常重要,说不定其中就隐藏着他们的阴谋。

两个文件一个是enc.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from Crypto.Util.number import *

with open('../secret/flag', 'rb') as f:
flag = f.read()

e = 65537

while True:
p = getPrime(1024)
q = 0x23333 + ((2 ** 1024 - 1) ^ p)
if isPrime(q):
break

n = p * q

c = pow(bytes_to_long(flag), e, n)

with open('output.txt', 'w') as f:
print(n, file=f)
print(c, file=f)

一个是output.txt

1
2
252512141941310802701221473362772656217272344779932223613726991993898786611923702512679535996463374977780377028390918003980896672945470020851425931374557742679101576399762239500592642130796147342430209907782577899773998685692654926591454486422689332597175671064655982527165290267825985733884171548134813019038707655971701683569459579633713409033747631799550405492825274552834061772374360574246464209025138119934022162644215938236619665146300639224371834061251176675654318999021919632956185273468999357525307464576349917940634000512292554533656276185832872630123325948320166709502442401562332275360500796782395330413
196582528742478115288825114686739654967451165033385324194513782729023376442481246572272979571518959300942988958326751937950797512666806927821108737279307734945069920341234443026087942805912715784099581834786550577486875889691313632902198180378159400130002905373523279292556875588606085023082681882176464063960718392101596606778983636752553020052719586672583987605986006710254746973188609838980833068817381518298924543658173745536767978331078524466703580483247941872953502987079624342801982258962689506419171140409432012382525623376175649355563533176437650057070240549778965465894707387466277984219123610913893808500

解法

p和q存在关系 q = 0x23333 + ((2 ** 1024 - 1) ^ p)

其中2 ** 1024 - 1转二进制为全1,此时与p做异或相当于 (2 ** 1024 - 1) - p

相当于接方程

  • q = 0x23333 + ((2 ** 1024 - 1) ^ p)
  • n = p * q

这样能求出来p,同十四题后续,求出私钥(n,d)然后解密即可

脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import gmpy2
from Crypto.Util.number import isPrime,long_to_bytes
from z3 import *
e = 65537
a = 144179
n = 252512141941310802701221473362772656217272344779932223613726991993898786611923702512679535996463374977780377028390918003980896672945470020851425931374557742679101576399762239500592642130796147342430209907782577899773998685692654926591454486422689332597175671064655982527165290267825985733884171548134813019038707655971701683569459579633713409033747631799550405492825274552834061772374360574246464209025138119934022162644215938236619665146300639224371834061251176675654318999021919632956185273468999357525307464576349917940634000512292554533656276185832872630123325948320166709502442401562332275360500796782395330413
m = 196582528742478115288825114686739654967451165033385324194513782729023376442481246572272979571518959300942988958326751937950797512666806927821108737279307734945069920341234443026087942805912715784099581834786550577486875889691313632902198180378159400130002905373523279292556875588606085023082681882176464063960718392101596606778983636752553020052719586672583987605986006710254746973188609838980833068817381518298924543658173745536767978331078524466703580483247941872953502987079624342801982258962689506419171140409432012382525623376175649355563533176437650057070240549778965465894707387466277984219123610913893808500
s = Solver()
p, q = Ints('p q')
s.add(p*q == n)
s.add(q == 0x23333 + ((2 ** 1024 - 1) - p))
# 检查是否有解
print(s.check())
# 打印出来解
print(s.model())
# _p = s.model()[p]
_p = 178353517795389103278069057744077762883736692087446846995296476441832846156523159741547004856863712172093080135105307949201069915610965730188885622061126863300790862944418998214803971668491176070858870494755749579593317013108730677311072523517822414575544161111226500156289656954727320833110098322857774489111
# _q = s.model()[q]
_q = 1415795690842487494861461334824710478061005806783810278133604715899829648977803391161472465543823849027033744766085408457719853203450892303961808578347261076977030480446487061498247932754918048594212457329256189244833669233732204162840587023004822587806349573359798083657588983752395471725258006766449792283
phi = (_p - 1) * (_q - 1)
d = gmpy2.invert(e, phi)
real_flag = pow(m, d, n)
r = long_to_bytes(real_flag)
print(r)

0x0f 题目十五

题目

文件显示,他们计划在9月6日对京东发起攻击,此时,电子锁突然从屋外反锁,随即我接到了阴暗面组织的电话,说想逃离这里,就需要从电脑里的京东logo中找办法,于是我打开了这个logo。

打开是一张图片

解法

binwalk查看是否存在其他文件

发现存在zlib外的信息,Hex fiend查看文件(windows可以使用010editor或者winhex)

发现PNG内容后还跟着有一大部分其他内容,拉到最后看了一下

是ELF文件,不过文件是倒着的,所以我们把PNG后面的内容保存,逆着写入到一个文件里

1
2
3
4
5
6
7
8
9
import os
with open('testaa', 'rb') as f:
data = f.read()

_len = len(data)
with open('testbb', 'wb') as f:
for i in range(_len):
f.write(data[_len-i-1:_len-i])
print("over")

查看文件是否是ELF,给文件附加执行权限chmod +x testbb

执行后

这个flag是错的。。。太坑了。。继续分析这个elf文件

binwalk testbb发现里面有很多zip

foremst -T testbb 提取出所有文件,发现有很多图片

试着拼了一下其中数字代表图片的位置。自己先把图片按照第一个数字解压到不同文件里先对每个文件里图片水平拼接然后输出到out目录里,再对所有水平拼接后的图片垂直拼接。

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
34
35
36
37
38
# coding:utf-8
import numpy as np
import cv2

def handle_pic(input_path, isVertical):
# input:
# 请把需要连接的图片放到同一个文件夹下面,图片名称最好具有相同的格式
N = 16 # 共有图片N张
M = 16 # 每M张合成一张纵向长图
# M = N # 如果仅需要合成单张图片,请解除此句的注释,令 M=N
# 路径可以是绝对路径,也可以是相对路径,注意路径中不能出现中文,否则无法被imread读取
save_path = '/Users/wautumnli/Downloads/output_Thu_Aug_26_20_20_16_2021/zip/flag/out/'
G = np.ceil(N / M) # 共分为G组
G = G.astype(np.int32)
for j in range(0, G):
imgs = []
# 把一组图像存到imgs里面
for i in range(j*M, min((j+1)*M, N)):
# 每个文件的路径
path = input_path + str(i) + '.png'
mat = cv2.imread(path)
imgs.append(mat)
# 判断条件是水平还是垂直拼接
if isVertical:
img = np.vstack(imgs)
cv2.imwrite(save_path + 'out_' + str(i) + '.png', img)
else:
img = np.hstack(imgs)
# 保存图片
cv2.imwrite(save_path + 'out_res' + '.png', img)


img_path = '/Users/wautumnli/Downloads/output_Thu_Aug_26_20_20_16_2021/zip/flag/'
# 先处理水平拼接
for i in range(16):
handle_pic(img_path + 'pic' + str(i) + '/flag_' + str(i) + '_', False)
# 垂直拼接
handle_pic(img_path + 'out/out_', True)

flag:JDSEC{3f8d190507f82cf6e78758b656130aff4f4080244484ec88b4acc3a42dbcf1f10b3ba5ad262f8d190507f14085a1efccdd1d}

0x10 题目十六

题目

原来logo当中隐藏的是一个京东双11秒杀活动图片,看来黑客组织的行动和京东双11有关,是得好好查查这次活动了。

一张图片

解法

binwalk查看没有问题,hex field查看没有问题。查看是否存在LSB隐写。使用stegsolve.jar,对图片低位隐写取值

发现是一张图片,保存下来

Flag:JDSEC{G00D_Game11!}

0x11 题目十七

题目

果然,活动页面中隐藏了需要加入购物车的商品信息,正当我按照指引把这些商品依次加入购物车的时候,突然不知道哪里来了一只黑猫跳上了电脑,删掉了好多文件,我需要把文件恢复回来。

解法

使用diskGenius恢复镜像文件

发现存在一个压缩文件,解压后是一个.supersecret.txt.swp文件,vim恢复

vim -r .supersecret.txt.swp恢复原txt文件,得到flag

flag:JDSEC{cat_0n_my_keyb0ard}

0x12 题目十八

题目

把文件恢复后,我突然发现桌面上出现了一个原来没有的文件,看来这个文件中一定隐藏了什么秘密。

1
-.---../..-/-----/-----/....-/.-/-.---../..-/-----/-----/....-/....-/-.---../..-/-----/-----/...../...--/-.---../..-/-----/-----/....-/...../-.---../..-/-----/-----/....-/...--/-.---../..-/-----/-----/--.../-.../-.---../..-/-----/-----/....-/----./-.---../..-/-----/-----/...../..-./-.---../..-/-----/-----/--.../--.../-.---../..-/-----/-----/-..../.----/-.---../..-/-----/-----/--.../....-/-.---../..-/-----/-----/-..../...--/-.---../..-/-----/-----/-..../---../-.---../..-/-----/-----/-..../...../-.---../..-/-----/-----/-..../....-/-.---../..-/-----/-----/...../..-./-.---../..-/-----/-----/--.../....-/-.---../..-/-----/-----/-..../---../-.---../..-/-----/-----/-..../----./-.---../..-/-----/-----/--.../...--/-.---../..-/-----/-----/...../..-./-.---../..-/-----/-----/-..../-.-./-.---../..-/-----/-----/-..../.----/-.---../..-/-----/-----/--.../...--/-.---../..-/-----/-----/--.../....-/-.---../..-/-----/-----/...../..-./-.---../..-/-----/-----/-...././-.---../..-/-----/-----/-..../----./-.---../..-/-----/-----/-..../--.../-.---../..-/-----/-----/-..../---../-.---../..-/-----/-----/--.../....-/-.---../..-/-----/-----/...../..-./-.---../..-/-----/-----/-..../..---/-.---../..-/-----/-----/-..../----./-.---../..-/-----/-----/-..../-.-./-.---../..-/-----/-----/-..../----./-.---../..-/-----/-----/-..../..---/-.---../..-/-----/-----/-..../----./-.---../..-/-----/-----/-..../-.-./-.---../..-/-----/-----/-..../----./-.---../..-/-----/-----/..---/./-.---../..-/-----/-----/-..../...--/-.---../..-/-----/-----/-..../..-./-.---../..-/-----/-----/-..../-../-.---../..-/-----/-----/..---/..-./-.---../..-/-----/-----/--.../-..../-.---../..-/-----/-----/-..../----./-.---../..-/-----/-----/-..../....-/-.---../..-/-----/-----/-..../...../-.---../..-/-----/-----/-..../..-./-.---../..-/-----/-----/..---/..-./-.---../..-/-----/-----/....-/..---/-.---../..-/-----/-----/...../-..../-.---../..-/-----/-----/...--/.----/-.---../..-/-----/-----/....-/--.../-.---../..-/-----/-----/....-/.-/-.---../..-/-----/-----/...--/....-/-.---../..-/-----/-----/...--/.----/-.---../..-/-----/-----/...--/.----/-.---../..-/-----/-----/--.../---../-.---../..-/-----/-----/...--/--.../-.---../..-/-----/-----/-..../---../-.---../..-/-----/-----/...--/--.../-.---../..-/-----/-----/--.../-..

解法

摩丝密码,在线摩丝解密

1
%u5cU004A%u5cU0044%u5cU0053%u5cU0045%u5cU0043%u5cU007B%u5cU0049%u5cU005F%u5cU0077%u5cU0061%u5cU0074%u5cU0063%u5cU0068%u5cU0065%u5cU0064%u5cU005F%u5cU0074%u5cU0068%u5cU0069%u5cU0073%u5cU005F%u5cU006C%u5cU0061%u5cU0073%u5cU0074%u5cU005F%u5cU006E%u5cU0069%u5cU0067%u5cU0068%u5cU0074%u5cU005F%u5cU0062%u5cU0069%u5cU006C%u5cU0069%u5cU0062%u5cU0069%u5cU006C%u5cU0069%u5cU002E%u5cU0063%u5cU006F%u5cU006D%u5cU002F%u5cU0076%u5cU0069%u5cU0064%u5cU0065%u5cU006F%u5cU002F%u5cU0042%u5cU0056%u5cU0031%u5cU0047%u5cU004A%u5cU0034%u5cU0031%u5cU0031%u5cU0078%u5cU0037%u5cU0068%u5cU0037%u5cU007D

看着像是url编码,把u5c删除掉,大写转小写

1
%u004a%u0044%u0053%u0045%u0043%u007b%u0049%u005f%u0077%u0061%u0074%u0063%u0068%u0065%u0064%u005f%u0074%u0068%u0069%u0073%u005f%u006c%u0061%u0073%u0074%u005f%u006e%u0069%u0067%u0068%u0074%u005f%u0062%u0069%u006c%u0069%u0062%u0069%u006c%u0069%u002e%u0063%u006f%u006d%u002f%u0076%u0069%u0064%u0065%u006f%u002f%u0042%u0056%u0031%u0047%u004a%u0034%u0031%u0031%u0078%u0037%u0068%u0037%u007d

在线url解码得flag

flag:JDSEC{I_watched_this_last_night_bilibili.com/video/BV1GJ411x7h7}