呜呜呜 T_T

记录一下蒟蒻在各大比赛挨打的过程。

# 2021.10.22 省赛(复现)

# misc

附件就一张图片,binwalk 没发现啥玩意,最后到处试 lsb 隐写给试出了一个 rar

拔下来的 rar 发现是损坏的,考虑伪加密,把加密位改回去

这里的 0 改成 4,原本以为没啥问题了,结果这里踩坑了。这里要用官方给的 lsb 隐写脚本跑出来的 rar 才是正确的 rar。

后面的步骤都很简单了,爆破出加密的 rar 密码为 123321,得到一张图片直接用 stegsolve 看 flag。

# 2021.8.30 DASCTF(复现)

有俩密码学的题

# Crypto

# let's play with rsa~

附件长这样:

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
from sympy import isprime,nextprime
from Crypto.Util.number import getPrime as getprime ,long_to_bytes,bytes_to_long,inverse
flag='flag{***************}'

def play():
p=getprime(1024)
q=getprime(1024)

n=p*q
e=65537

print "Hello,let's play rsa~\n"
print 'Now,I make some numbers,wait a second\n'
n1=getprime(200)
n2=getprime(200)
number=n1*n2
print "Ok,i will send two numbers to you,one of them was encoded.\n"
print "Encode n1:%d,\n"%(pow(n1,e,n))
print "And n2:%d.\n"%n2

print "Information that can now be made public:the public key (n,e):(%d,%d)\n"%(n,e)
while True:
try:
c=int(raw_input("ok,now,tell me the value of the number (encode it for safe):"))
except:
print "Sorry,the input is illeagal, and the integer is accept~"
else:
break
d=inverse(e,(p-1)*(q-1))
m=pow(c,d,n)
if m==number:
print "It's easy and interesting,didn't it?\n"
print "This is the gift for you :"+flag
else:
print "Emmmmm,there is something wrong, bye~\n"

if __name__ == '__main__':
play()

数学原理很简单:

exp 如下:

1
2
3
4
5
6
7
8
from Crypto.Util.number import *
import gmpy2
en_n1 = 1309721910589292483737401896023705647211812731131580022207997317781086527420162694426783098998244562068230335429061546502019166975754786167341689047014873958107404120012933517153896824577108373020327789333970129263835075665364474808938834288415903375301139260812397188033692847643071939844953726931774517258280654227664887556336036095280951203307978647462380596353268816595074090830724134701722961596409878278764247168746397167847040206659595961690456943906329271303804282136442317185552336464229518976466931265098174562935244202362365634788701457135344490298509297318209626645153514784129383468209964398541421466276
n = 12837770558555314064794558480082731445733882018381629916163024669576913542314586587530283320606488797929692460622707042752475883949512350557684519969053352832577190628394534732768969813760882691828041106105916556730296206192621778367752135858508793676525121086890158474077244689335284589013548347756711712889737164840475886374605781536567359597200412748537326979090940986741854313956791578704511827287026891681707519188758403649811968478863567711653557073172575381628473942814925653831626597042079483642684004219931450549540680966665970171852575497645457016481998448325634229033075903634430806140076432661903094828593
e = 65537
n2 = 1362359474479550927452891208121227746732073198634558158536609
c = en_n1 * pow(n2,e,n)
print(c)
# ezRSA

这题原理和上题类似,附件如下:

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
from secret import flag
from Crypto.Util.number import *
from random import getrandbits
from hashlib import sha256


class EzRsa:
def __init__(self):
self.E = 0x10001
self.P = getPrime(1024)
self.Q = getPrime(1024)
while GCD((self.P-1)*(self.Q-1), self.E) != 1:
self.Q = getPrime(1024)
self.N = self.P*self.Q

def encrypt(self):
f = getrandbits(32)
c = pow(f, self.E, self.N)
return (f, c)

def encrypt_flag(self, flag):
f = bytes_to_long(flag)
c = pow(f, self.E, self.N)
return c


def proof():
seed = getrandbits(32)
print(seed)
sha = sha256(str(seed).encode()).hexdigest()
print(f"sha256({seed>>18}...).hexdigest() = {sha}")
sha_i = input("plz enter seed: ")
if sha256(sha_i.encode()).hexdigest() != sha:
exit(0)


if __name__ == "__main__":
proof()
print("welcome to EzRsa")
print("""
1. Get flag
2. Encrypt
3. Insert
4. Exit
""")
A = EzRsa()
coin = 5
while coin > 0:
choose = input("> ")
if choose == "1":
print(
f"pow(flag,e,n) = {A.encrypt_flag(flag)}\ne = 0x10001")
exit(0)
elif choose == "2":
f, c = A.encrypt()
print(f"plain = {f}\ncipher = {c}")
coin -= 1
elif choose == "3":
q = getrandbits(1024)
n = A.P*q
f = getrandbits(32)
c = pow(f, 0x10001, n)
print(f"plain = {f}\ncipher = {c}")
coin -= 1
elif choose == "4":
print("bye~")
else:
print("wrong input")
print("Now you get the flag right?")

给了 5 次机会 (coin),2 和 3 选项分别能得到 n 和 p,数学原理如下:

exp 如下:

选项 2 和 3 各选两次拿数据,最后一次拿 flag 的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from random import *
#from math import *
from Crypto.Util.number import *
import gmpy2
e = 0x10001
f1 = 3991424584
c1 = 23299859078129861414913771548219349721900206664014819386195794916044845964332637389648259329302749550436346202286946048713385410408064459859081918493047190943298495292861013654519793379809752456534138428868643899609668723735710829524825269361397275459708970559074552900236486895513774078684184834805376606088247533387016219365170743668987289463976754247014480713302197196568222170824912241303970513628344421242260649810302948949131617868038594231101232079019013330304215113673368314368833706712612127152921982153341480322701194423727871123662394240685540736238634699368430418964615398086626177026843559305313991443227
f2 = 3302952139
c2 = 16135167708023658331902606113227526506624892717052237702988935145355289623080800253295795703695347360875254861269833966623609514382014163433041295324806175024336762186717776686444629275737425480610600987793377115715370987547355442485973887920207336811930557011003908778677685189445607074026451925553282013998440786813828560563175818728704616901557779531236686737383795809573571053296171873412845580984730014998699951618614567444985737702781759475230163602992352950497827705875149910442039431153623052044891404971539003392860077134760784914141313151742913299690411764314019909465761008921434322476865096137861232855781
n = gmpy2.gcd(pow(f1,e) - c1,pow(f2,e) - c2)
print(n)
c3 = 290608034256274369700862715363350323486028744781731905934249350715041586859408919647347827785586727942092508209115402506051655157392015883300023889210219576419324704609311096050860136030302584481540004322444602941867627050991572899014259628993547816246063508914512684313837142913444152620481715232869398984200565254080136273801468740882064342549655664616243374405422083085368533066537431942688830581503260516034879177548907813082280973258211700086334417911908732693940787281869354657664111312741521516275861135779300654363453173656735944975815042979883029464520576788180760677023541130131734670871708628401566092056
c4 = 19477721821886525117440143496319431500495385071913979141466226040526802160059201844862618364367741954042703804931248758421694329933382467780307210147901496300326789151918308642829330627052858106511054852272266315174702986664133983456742201333616464739367956812505831108567707073824178369443747106670498181714026256534321719627886311877207237167881226028217405406516689294193625979523781236934797180792371554750209628867494205548515578343356570418434460849979994288195296861844688172042575939423362750874494740696017989524225414610737548788064086913880409416592656292914866756979555717165005851927596841150843763549837
f3 = 790182690
f4 = 2129564814
p = gmpy2.gcd(pow(f3,e) - c3,pow(f4,e) - c4)
q = n // p
c = 24952279514997224947101022682449626128048315926803834959283021867551136554920048640317181593937537055086263973539743885388583210115706780021523202021772462316835425921121320529162432793833128629912344112656578819828486682363773819631694824476713219629652576476637315910977274832345854578059628785051135439346323100743046829886707064789413910491823509991850949661231750479103393176692414195918532925181456936717164879556950696080788364971454803842425311834060331270850687515410797773548975263226563726398807177996001159332682433166744595590323697981578101554722234248005684614174799841980158652033235878038837817713173
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))

# 2021.8.23 祥云杯

做了两个题,分最低的俩,呜呜呜,提取密码都是 GAME

# Misc

# 鸣雏恋 附件下载

下载下来一个 60 多 M 的 docx,改后缀 zip 翻到了_rels 里面的 key.txt 和 love.zip,key.txt 是零宽隐写,解密网站,直接全部复制进去出来的就是 love.zip 的密码。

love.zip 里面只有两种图片,盲猜是二进制之后转 ascii,图片太多写脚本跑。

1
2
3
4
5
6
7
8
9
10
import os
ans = ''
for i in range(129488):
filename = str(i) + '.png'
fsize = os.path.getsize(filename)
if fsize > 300:
ans += '1'
else:
ans += '0'
print(ans)

一种 262 字节一种 435 字节,用 300 为界限划分,出来的二进制码转 ascii,发现是 base64 的图片编码,拿去解码就得到了 flag

1
flag{57dd74fb21bb1aee50f19421bf836f23}

# Crypto

# Random_RSA 附件下载

第一次在大比赛里面做出 rsa 的题,这题加密算法不难理解,题目贴一下反正不大,print 的数据都给了.

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
from Crypto.Util.number import *
import gmpy2
import libnum
import random
import binascii
import os

flag=r'flag{}'

p=getPrime(512)
q=getPrime(512)
e=0x10001
n=p*q
ct=pow(flag,e,n)
print("n="+ n)
print("ct="+ ct)

dp=r''
seeds = []
for i in range(0,len(dp)):
seeds.append(random.randint(0,10000))

res = []
for i in range(0, len(dp)):
random.seed(seeds[i])
rands = []
for j in range(0,4):
rands.append(random.randint(0,255))

res.append(ord(dp[i]) ^ rands[i%4])
del rands[i%4]
print(str(rands))

print(res)
print(seeds)

没有给 dp, 应该是要我们求。告诉了 dp 是多少位的,和 seeds 是一样的 154 位,程序是把 dp 的每一位,异或加密了,生成的 seeds 是随机的题目也给了,根据这个 seeds 去生成随机数来对 dp 的每一位进行异或加密,一开始用 python3 跑出来的 rands 是错的 特地装了个 python2 去跑了个随机数.

得到正确的 rands 之后拿去解密 dp, 脚本如下

1
2
3
4
5
6
7
dp = []
ans = [2, 54, 128, 242, 87, 16, 228, 64, 84, 78, 71, 0, 73, 160, 128, 200, 124, 165, 114, 2, 241, 124, 118, 52, 127, 193, 142, 35, 230, 138, 5, 135, 40, 188, 28, 108, 167, 207, 166, 181, 127, 51, 168, 146, 168, 204, 62, 134, 37, 219, 234, 255, 50, 117, 194, 243, 124, 137, 221, 88, 188, 191, 143, 122, 49, 64, 143, 8, 190, 184, 85, 102, 236, 196, 34, 183, 207, 157, 160, 79, 153, 202, 184, 244, 157, 48, 211, 255, 113, 58, 117, 131, 33, 36, 246, 250, 85, 41, 203, 101, 189, 50, 81, 127, 233, 114, 233, 251, 118, 137, 76, 61, 158, 144, 233, 80, 169, 174, 1, 172, 4, 176, 137, 255, 186, 244, 28, 17, 12, 55, 246, 235, 127, 167, 114, 154, 151, 235, 155, 39, 252, 83, 87, 97, 255, 47, 14, 143, 28, 176, 164, 235, 35, 102]
res = [55, 5, 183, 192, 103, 32, 211, 116, 102, 120, 118, 54, 120, 145, 185, 254, 77, 144, 70, 54, 193, 73, 64, 0, 79, 244, 190, 23, 215, 187, 53, 176, 27, 138, 42, 89, 158, 254, 159, 133, 78, 11, 155, 163, 145, 248, 14, 179, 23, 226, 220, 201, 5, 71, 241, 195, 75, 191, 237, 108, 141, 141, 185, 76, 7, 113, 191, 48, 135, 139, 100, 83, 212, 242, 21, 143, 255, 164, 146, 119, 173, 255, 140, 193, 173, 2, 224, 205, 68, 10, 77, 180, 24, 23, 196, 205, 108, 28, 243, 80, 140, 4, 98, 76, 217, 70, 208, 202, 78, 177, 124, 10, 168, 165, 223, 105, 157, 152, 48, 152, 51, 133, 190, 202, 136, 204, 44, 33, 58, 4, 196, 219, 71, 150, 68, 162, 175, 218, 173, 19, 201, 100, 100, 85, 201, 24, 59, 186, 46, 130, 147, 219, 22, 81]
for i in range(len(res)):
dp.append(chr(res[i] ^ ans[i]))
dp = ''.join(dp)
print(dp)

得到 dp 之后,就是一个简单的 dp 泄露题了,拿模板去套.(模板是 la 佬的 磕头)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import gmpy2 as gp
e = 0x10001
n = 81196282992606113591233615204680597645208562279327854026981376917977843644855180528227037752692498558370026353244981467900057157997462760732019372185955846507977456657760125682125104309241802108853618468491463326268016450119817181368743376919334016359137566652069490881871670703767378496685419790016705210391
dp = 5372007426161196154405640504110736659190183194052966723076041266610893158678092845450232508793279585163304918807656946147575280063208168816457346755227057
c = 61505256223993349534474550877787675500827332878941621261477860880689799960938202020614342208518869582019307850789493701589309453566095881294166336673487909221860641809622524813959284722285069755310890972255545436989082654705098907006694780949725756312169019688455553997031840488852954588581160550377081811151
for x in range(1, e):
if(e*dp%x==1):
p=(e*dp-1)//x+1
if(n%p!=0):
continue
q=n//p
phin=(p-1)*(q-1)
d=gp.invert(e, phin)
m=gp.powmod(c, d, n)
if(len(hex(m)[2:])%2==1):
continue
print('--------------')
print(m)
print(hex(m)[2:])
print(bytes.fromhex(hex(m)[2:]))

# 2021.7.31 DASCTF

菜鸡想吐槽:肝了半天的题目都成 200 分了,果然我是最菜的。

# Misc

# red_vs_blue 传送门

题目要 nc 连接,思路很简单,就是 nc 连上之后,有 66 个结果随机选择哪一个队,选择错了就退回到第一关,要连续选择正确 66 个结果。

1
2
3
4
5
6
7
8
9
10
11
root@tsuppari:/home/tsuppari# nc node4.buuoj.cn 27935
Here are 66 AWD Games will begin!
The winner is between Red Team and Blue Team
To get the flag if you predict the results of all games successfully!
Game 1
choose one [r] Red Team,[b] Blue Team:
r
Your choice Red Team
The result Blue Team
Sorry!You are wrong!
Play again? (y/n): y

每次 nc 进入,66 个结果都是一样的,所以直接写脚本跑。19 行代码蒟蒻改来改去写了一个钟头。还是太 fw 了。就是一个不断试错暴力破解的过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
r = remote('node4.buuoj.cn',27935)
context.log_level='debug'
ans = []
r.recvuntil(b'To get the flag if you predict the results of all games successfully!\n')
while True:
r.recvuntil(b'choose one [r] Red Team,[b] Blue Team:\n')
r.sendline(b'r')
r.recvline()
result = r.recvline()#接受第二行的结果
if b'Blue' in result:
ans.append(b'b')
r.recv()
r.sendline(b'y')
for i in ans:
r.recvuntil(b'choose one [r] Red Team,[b] Blue Team:\n')
r.sendline(i)
else:
ans.append(b'r')
# funny_maze 传送门

题目也是 nc 连接,连上去有 3 个选择,2 没啥用,3 介绍游戏规则,就是在 10s 之内计算出从起点走到终点的路径,超过了 10s 就会出 timeout。如果是最短路径下面的脚本就得改一改,反正思路是一样的都是 dfs (深搜),oier 的必修之路。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@tsuppari:/home/tsuppari# nc node4.buuoj.cn 27619                                            

Hello! Welcome to my maze, You can choose 1, 2 or 3.
1.Start, and You only have three seconds to complete the level.
2.Hint! I need Hint!
3.Introduction to this game
1
###########
# # # # E
# # # ### #
# #
# # # #####
# # # # #
# # # ### #
# # # # #
# ##### # #
S # #
###########
Please enter your answer:

time out!!!root@tsuppari:/home/tsuppari#

一个简单的 dfs 脚本,60 多行代码改了 2 个钟头,写脚本能力太弱了。

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
from pwn import *
r = remote('node4.buuoj.cn',27619)
context.log_level='debug'
def dfs(start_x,start_y):
x1 = start_x
y1 = start_y - 1
x2 = start_x + 1
y2 = start_y
x3 = start_x
y3 = start_y + 1
x4 = start_x - 1
y4 = start_y
if x1 >= 0 and x1 <= height:#越界处理
if y1 >= 0 and y1 <= width-1:
if maze[x1][y1] == 0 :
maze[x1][y1] += maze[start_x][start_y] + 1
dfs(x1,y1)
if x2 >= 0 and x2 <= height-1:
if y2 >= 0 and y2 <= width-1:
if maze[x2][y2] == 0 :
maze[x2][y2] += maze[start_x][start_y] + 1
dfs(x2,y2)
if x3 >= 0 and x3 <= height-1:
if y3 >= 0 and y3 <= width-1:
if maze[x3][y3] == 0 :
maze[x3][y3] += maze[start_x][start_y] + 1
dfs(x3,y3)
if x4 >= 0 and x4 <= height-1:
if y4 >= 0 and y4 <= width-1:
if maze[x4][y4] == 0 :
maze[x4][y4] += maze[start_x][start_y] + 1
dfs(x4,y4)
r.recv()
r.sendline(b'1')
while True:
maze = r.recvuntil(b'Please enter your answer:\n').splitlines()[:-1]
height = len(maze)
width = len(maze[0])
start_x = 0
start_y = 0
end_x = 0
end_y = 0
for i in range(height):
maze[i] = list(maze[i])
for j in range(width):
if maze[i][j] == 32:
maze[i][j] = 0#空地设置成0
if maze[i][j] == 35:
maze[i][j] = -1#障碍物设置成-1
if maze[i][j] == 69:
maze[i][j] = 0#标记为终点位置
end_x = i
end_y = j
if maze[i][j] == 83:
maze[i][j] = 1#标记起点的位置
start_x = i
start_y = j

dfs(start_x,start_y)
ans = maze[end_x][end_y]
ans = str(ans)
r.sendline(ans.encode())
r.recv()

DASCTF 的比赛自己做出来的就 2 个题😔,后面会复现一下 pwn。

# 2021.5.15 ciscn

# Misc

# 隔空传话

下载下来一个 data.txt,一堆数字与字符,查找后发现这是 PDU 短信的编码,前面四句话与后面几句话不一样,前四句话翻译如下。

1
2
3
4
5
6
7
8
9
hello,bob!what is the flag?

the first part of the flag is the first 8 digits of your phone number

那其他部分呢

看看你能从这些数据里发现什么?w465

Receipient:+861503044200

flag 前 8 位为 15030442,后面的 PDU 翻译过来都是 16 进制字符串,且发送的时间都不相同。于是写脚本进网站翻译。

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
from selenium import webdriver
with open('data.txt','r') as f:#data.txt为下载下来的文件,删去了前4行
data = f.read()
data = data.splitlines()
browser = webdriver.Chrome('C:\Program Files\Google\Chrome\Application\chromedriver.exe')
url = "http://www.sendsms.cn/pdu/"
browser.get(url)
output = ''
for i in data:
browser.find_element_by_name("smsText2").clear()
browser.find_element_by_name("smsText2").send_keys(i)
browser.find_element_by_xpath("//input[@name='checkButton']").click()
recv = browser.find_element_by_name("smsOut").get_attribute('value')
recv = recv.split()
n = 0
txt = ''
for j in recv:#循环之后的 txt 为 短信时间+16进制码
if n == 3:
txt += j
if n == 13:
txt += j
txt += '\n'
n += 1
output += txt
with open('out.txt','w') as f:
f.write(output)
browser.quit()

小破脚本跑了很久,最后得到的 out.txt 如下:

按照时间排序,用脚本排序,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
with open('out.txt','r') as f:
data = f.read()
data = data.splitlines()
n1 = []
n2 = []
output = ''
for i in data:
time = i[:8]
txt = i[8:]
minute = int(time[3:5])
sec = int(time[6:8])
num = minute*60+sec
n1.append(num)
n2.append(txt)
for i in range(0,5000):#排序输出
for j in range(len(data)):
if i == n1[j]:
output += n2[j]
with open('output.txt','w') as f:
f.write(output)

发现文件 output.txt 的开头 89504e47 是 png 文件头,但是宽被修改过,联系前面的信息:w465,可猜测宽为 465,于是得到图片

1
CISCN{15030442_b586_4c9e_b436_26def12293e4}

# 2021.5.9 redhat

# Misc

# 签到

下载下来一个 EBCDIC.txt,作为一个合格的萌新,直接把 EBCDIC 拿去 Google

当时打比赛的时候我是对着这张表一个一个手动翻译,时间也不长 2 分钟就好了。后面看了别的大佬的 blog 发现可以用 Linux 自带的 dd 命令解出,或者是用 010。

1
flag{we1c0me_t0_redhat2021}
# colorful_code

下载下来两个文件 data1,data2。

思路:仔细观察 data1,文件大小有 15kb,data2 只有 1kb. 查看 data2,其中后面大部分数据,从 14 开始后面是每 3 位数据都相同,观察前面的数据,共有 20 组(0-19)每组 3 个数据,联系题目 colorful 这题应该跟画图有关,每三位代表 RGB 的三个数据。

而 data1 中是由 0-19 整数组成,推测 data1 中每一个整数代表一个序号,序号对应 data2 中的色块序号。

思路清晰,开始写脚本跑

1
2
3
4
5
6
7
8
9
from binascii import *
with open('data2','rb') as f:
f = hexlify(f.read()).decode()
color_list = []
for i in range(0,len(f),2):
num = f[i:i+2]
color_list.append(int(num,16))
for i in range(0,len(color_list),3):
print(color_list[i],color_list[i+1],color_list[i+2])

这个输出的前 20 组数据就是我们要的数据,复制出去作为 output,写下一个绘图脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from binascii import *
from PIL import Image
with open('data1','rb') as f:
f = f.read()
data = f.split()
with open('output.txt','rb') as f:
f = f.read()
num_list = f.split()
print(num_list)
print(data)
width,height = 37,191
pic = Image.new("RGB",(width,height))
n = 0
for i in range(width):
for j in range(height):
m = int(data[n])
j1,j2,j3 = int(num_list[m*3]),int(num_list[m*3+1]),int(num_list[m*3+2])
pic.putpixel([i,j],(j1,j2,j3))
n += 1
pic.show()
pic.save('flag.png')

data1 共由 7067 个数据,7067=37*191,不知道哪个是高哪个是底,都试一遍。而且一开始我不知道它是一行一行写还是一列一列写,所以都试试。试出来的结果就是

然后就涉及到我的知识盲区了。后面知道是一种叫做 npiet 的隐写术,有在线解码脚本。

1
flag{88842f20-fb8c-45c9-ae8f-36135b6a0f11}
編集日 閲覧数

*~( ̄▽ ̄)~[お茶]を一杯ください

tsuppari Alipay

Alipay

tsuppari PayPal

PayPal