校赛

考点

misc

帧率提取 汉信码 base加密 ascii85加密 寄生文件

区块链

摩斯音频提取 pyc隐写

re

ios逆向,将ipa改后缀解压,反汇编

安卓逆向

rc4,base64魔改

upx特征码修改

z3

鸿蒙逆向 har解包 然后去专门的反汇编

MISC

迷宫

一个个画出来即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'''a='2 2 3 2 1 2 2 2 2 2 2 3 2 1 2 3 3 3 3 4 4 3 3 4 3 3 2 3 3 4 1 4 1'
for i in range(len(a)):
if(a[i]==' '):
continue
elif(a[i]=='1'):
print("上",end='')
elif (a[i] == '2'):
print("右",end='')
elif (a[i] == '3'):
print("下",end='')
elif (a[i] == '4'):
print("左",end='')'''
a='flag { W o w _ t h i s _ 1s _ a N _ A m a z 1 i ng _ Ma2e}'
for i in range(len(a)):
if(a[i]!=' '):
print(a[i],end='')

what can i say

给了一个gif文件,看了1000张照片后发现所有照片没有异常,换个方向

gif帧数间隔隐写(江哥笔记立大功)有事没事多看看我江哥笔记好吗

kali下使用

**identify -format "%s %T \n" flag.gif > 1.txt**

**identify -format "%T \n" flag.gif > 1.txt**

1
identify -format "%T \n" attachment.gif > 2.txt

1747125334728-9488e4b7-a666-499a-ad7f-467d3ce84f29.png

得到asill码,然后转换一下

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
# 文件名:ascii_converter.py

def text_to_ascii(input_path, output_path):
"""
将文本文件内容转换为 ASCII 码并写入输出文件(不换行)。
"""
try:
with open(input_path, 'r', encoding='utf-8') as infile, \
open(output_path, 'w', encoding='utf-8') as outfile:

all_ascii = []
for line in infile:
line = line.rstrip('\n')
ascii_values = [str(ord(char)) for char in line]
all_ascii.extend(ascii_values)

outfile.write(' '.join(all_ascii))
print(f"[成功] 文本转 ASCII 已写入 {output_path}")
except FileNotFoundError:
print(f"[错误] 输入文件未找到: {input_path}")
except Exception as e:
print(f"[错误] 转换失败: {e}")


def ascii_to_text(input_path, output_path):
"""
将 ASCII 文件内容转换为文本并写入输出文件(不换行)。
"""
try:
with open(input_path, 'r', encoding='utf-8') as infile, \
open(output_path, 'w', encoding='utf-8') as outfile:

content = infile.read().replace(',', ' ')
ascii_values = content.strip().split()
try:
chars = [chr(int(code)) for code in ascii_values]
outfile.write(''.join(chars))
print(f"[成功] ASCII 转文本已写入 {output_path}")
except ValueError:
print("[错误] 文件中包含非数字内容,转换失败。")
except FileNotFoundError:
print(f"[错误] 输入文件未找到: {input_path}")
except Exception as e:
print(f"[错误] 转换失败: {e}")


if __name__ == "__main__":
# 示例使用
# 将文本转为 ASCII(写入 ascii_output.txt)
# text_to_ascii('2.txt', 'ascii_output.txt')

# 将 ASCII 转为文本(写入 text_output.txt)
ascii_to_text('2.txt', 'text_output.txt')

得到经过多层base加密的密文

1
7OkS]MY9bjSC'\]e<s\zPl)Xs2pNm=6C/hu)IfXt:X^]%Rm$:A[y]<W>gPlF+HjM/0[ty>a|y,O8)w^962h,*a,gJHFdkm+1JsQnsD(h44QDBL0d;Dh\mu+B.kq8&qL[<,%R'z[t(qGIUBr3.l2BvR[tDqMcR|<67pH5:EY8#'Kb=ZDJ<qF[7][s?U[.'}lk<0t,fp_jUS<sjH650/1kiq)(bMUTW}u[J.;7

一把梭

1746947036499-60e57351-8c49-4581-9fd3-dfc533714e92.png

key :Th1s_i5_P@sSVV0rd_f0r_Z1p

可恶 这是个汉信码

1746949495259-f07ea056-e546-40f3-a706-e149ee9485ae.png

https://tuzim.net/hxdecode/

1746949519365-9fa47b7c-93c1-4fe5-b5e4-8271175acf28.png

听说好像有什么东西被寄生了,而且是同名的

mspaint flag.png:flag.txt (nt)

到这里发现没报错 然后用文本读取

notepad flag.png:flag.txt

chain

题目(提供源码,nc访问) 43.162.126.171:20000

rpc(货币节点,添加至metamask) 43.162.126.171:8545

水龙头(提供货币,浏览器访问) 43.162.126.171:8080

Can you make the isSolved() function return true?

[1] - Create an account which will be used to deploy the challenge contract

[2] - Deploy the challenge contract using your generated account

[3] - Get your flag once you meet the requirement

[4] - Show the contract source code

[-] input your choice: 1

[+] deployer account: 0x508d6694605E94D5F5Cd83927D1430dF88a72454

[+] token: v4.local.zKilVTo3F9RnfxyFFcMtmKcQooisTzmINMREDPWC2-LFBA6mXK-RDOJGLdGYZowa7OcK6fEa3sJxJRcovorbbC4f3JbEdSAZ8SI3wKqocvNpHHG6asfPKTzbS8uqz1MdQAdKMp58BVcQHTjvx83Go4LUXLC0KsSpxafT52TJkSbr7A.R3JlZXRlcg

[+] please transfer more than 0.002 test ether to the deployer account for next step

1746941734386-eaf3e2f0-a251-4ff3-abb7-19894e4ce3db.png

给了我们交易地址和交易hash

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
源码
[-] input your choice: 4
contracts/Example.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;

contract Greeter {
string greeting;

constructor(string memory _greeting) {
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
greeting = _greeting;
}

function isSolved() public view returns (bool) {
string memory expected = "EasyMiscSignin";
return keccak256(abi.encodePacked(expected)) == keccak256(abi.encodePacked(greeting));
}
}

function isSolved() public view returns (bool) {

    string memory expected = "EasyMiscSignin";

    return keccak256(abi.encodePacked(expected)) == keccak256(abi.encodePacked(greeting));

}

可以看到我们需要满足keccak256(abi.encodePacked(expected)) == keccak256(abi.encodePacked(greeting));但expexted已经是EasyMiscSignin,所以我们需要让greeting也是EasyMiscSignin

添加rpc

http://43.162.126.171:8545

添加网络,其中网络名称随便写,rpc填题目的第二个rpc地址,链id填错会告诉你正确的,照着填就行,货币符号自己随便。

1746943232585-0a827c21-0a99-4db2-8ab9-ba6cafda8d4f.png

在浏览器搜索remix并打开 复制源码进去

1746943598796-70ef4313-199a-434c-aed8-4fa7e7379275.png

contract address: 0xA6fAaF82611e37383b64a1580F84fEDD38eb5BD4

[+] transaction hash: 0x06a64470718b514cd5b21819c31ab7f125102a4186e114e4c5bfe0b1bf75fe7f

1746944085243-1072529e-e5a3-4ce5-97c2-730034925144.png

然后选择Injected Provider - MetaMask,这边注意networks的id是否一样,然后在At Address中输入前面的合约地址:0xA6fAaF82611e37383b64a1580F84fEDD38eb5BD4

1746944228626-99835d46-c8e8-426d-9fcf-fba1c1751986.png

下面填EasyMiscSignin

然后点击setGreeting

提示我们钱包里面没有gas fee 所以给钱包地址充钱

1746945614274-35d34f94-71b0-4954-afca-e91d6ec24d66.png

1746946002834-43904793-490a-4b35-a153-0b82e2ca8a6b.png

然后发送之前账号的token

1746946060655-03ceaa5e-b5f3-40d2-a31e-dafbed4a12d6.png

flag{72ada6f4-ae2e-4239-b37c-99cf760753c5}

四杀(keyboard)

python .\main.py .\keyboard.pcapng

1747116024696-4ffb8a67-268e-4609-804e-ff4a8db3db25.png

║ 2.1.1 => Host ║

║ baaaaaaaacaaaaacaab

1747116056311-fc3ccb44-cf9f-4704-9610-92a77b8fb404.png
https://www.yuque.com/qetxjul27/wn9kli/vys765odvcxlihim?single[CAPSLOCK]d[CAPSLOCK]oc

1747116085558-87955479-8f79-4769-a611-5ac31e012d1f.png

先复制一下数据

1
330D0D0A8BD11868BB020000E300000000000000000000000002000000400000007336000000640064016C006D015A010100640064026C025A026403640484005A036405640684005A04650564076B027232650483000100640253002908E900000000A901DA034145534E63020000000000000005000000030000004300000073480000007C00640117317D027C026A00640283017D027C026A016403640483027D0274026A037C0274026A0483027D0374056A067C0183017D017C036A077C0183016A0883007D047C04534029054EDA0A71657478736F636F6F6CFA057574662D38E918000000F301000000412909DA06656E636F6465DA05726A7573747203000000DA036E6577DA084D4F44455F454342DA0862696E6173636969DA09756E6865786C696679DA0764656372797074DA066465636F64652905DA0178DA06636970686572DA036B6579DA03616573DA04666C6167A9007215000000FA1A2F686F6D652F6B616C692F4465736B746F702F666C61672E7079720E00000004000000F30E000000000108010A010C010E010A010E01720E000000630000000000000000030000000300000043000000733C00000064017D007400640283017D0174017C017C0083027D0274027C028301016864037C026B06723074026404830101756E0874026405830101546400537929064EDA60626536666236626162663739326362626633343838336139333536626637333735376339326138333465666162346264633139366634343736633637313563343965666430626331306234363364393463353032303435646533353063323637FA17506C6561736520696E70757420796F7572206B65793A207214000000FA13576F772C20796F752066696E64206974212121FA084F68206E6F2121212903DA05696E707574720E000000DA057072696E742903DA0163DA016B7214000000721500000072150000007216000000DA046D61696E10000000F30E0000000001040108010A01080108010A027220000000DA085F5F6D61696E5F5F2906DA0D43727970746F2E4369706865727203000000720C000000720E0000007220000000DA085F5F6E616D655F5F721

听视频发现是莫斯电报,那把音频轨道分离出来然后在线解谜一下

https://dimorse.com/zh/morse-code-audio-decoder/

1747118509045-0d820e5c-e6fb-44e9-87dd-d05bfd2fc76c.png

1747118541230-893ce483-5359-4c5f-853d-15b38ecec8bb.png

补齐数据然后看看十六进制转字符

1
5000000721500000072150000007216000000DA083C6D6F64756C653E01000000F30A0000000C010802080C080A0801

330D0D0A8BD11868BB020000E300000000000000000000000002000000400000007336000000640064016C006D015A010100640064026C025A026403640484005A036405640684005A04650564076B027232650483000100640253002908E900000000A901DA034145534E63020000000000000005000000030000004300000073480000007C00640117317D027C026A00640283017D027C026A016403640483027D0274026A037C0274026A0483027D0374056A067C0183017D017C036A077C0183016A0883007D047C04534029054EDA0A71657478736F636F6F6CFA057574662D38E918000000F301000000412909DA06656E636F6465DA05726A7573747203000000DA036E6577DA084D4F44455F454342DA0862696E6173636969DA09756E6865786C696679DA0764656372797074DA066465636F64652905DA0178DA06636970686572DA036B6579DA03616573DA04666C6167A9007215000000FA1A2F686F6D652F6B616C692F4465736B746F702F666C61672E7079720E00000004000000F30E000000000108010A010C010E010A010E01720E000000630000000000000000030000000300000043000000733C00000064017D007400640283017D0174017C017C0083027D0274027C028301016864037C026B06723074026404830101756E0874026405830101546400537929064EDA60626536666236626162663739326362626633343838336139333536626637333735376339326138333465666162346264633139366634343736633637313563343965666430626331306234363364393463353032303435646533353063323637FA17506C6561736520696E70757420796F7572206B65793A207214000000FA13576F772C20796F752066696E64206974212121FA084F68206E6F2121212903DA05696E707574720E000000DA057072696E742903DA0163DA016B7214000000721500000072150000007216000000DA046D61696E10000000F30E0000000001040108010A01080108010A027220000000DA085F5F6D61696E5F5F2906DA0D43727970746F2E4369706865727203000000720C000000720E0000007220000000DA085F5F6E616D655F5F7215000000721500000072150000007216000000DA083C6D6F64756C653E01000000F30A0000000C010802080C080A0801

ai分析这是一个pyc文件,

1747119456480-e7696314-924c-414a-a29a-6e160aefaa91.png

直接uncompyle6

1747119824508-cd8c8c5d-d2ba-4f04-be98-cdffd1caca32.png

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 Crypto.Cipher import AES
import binascii

def decrypt(x, cipher):
key = x + "qetxsocool"
key = key.encode("utf-8")
key = key.rjust(24, b'A')
aes = AES.new(key, AES.MODE_ECB)
cipher = binascii.unhexlify(cipher)
flag = aes.decrypt(cipher).decode()
return flag


def main():
c = "be6fb6babf792cbbf34883a9356bf73757c92a834efab4bdc196f4476c6715c49efd0bc10b463d94c502045de350c267"
k = input("Please input your key: ")
flag = decrypt(k, c)
print(flag)
if "flag" in flag:
print("Wow, you find it!!!")
else:
print("Oh no!!!")


if __name__ == "__main__":
main()

这是我们之前拿到的key还记得吗,不需要爆破

这里还傻傻的写了一个爆破脚本

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 Crypto.Cipher import AES
import binascii
import string
from itertools import product

def decrypt(x, cipher_hex):
key = (x + "qetxsocool").encode("utf-8")
key = key.rjust(24, b'A') # AES-192 key
aes = AES.new(key, AES.MODE_ECB)
cipher = binascii.unhexlify(cipher_hex)
try:
result = aes.decrypt(cipher).decode("utf-8")
if "flag" in result:
print(f"[+] Found! x = '{x}'")
print(f"[+] Decrypted = {result}")
return True
except:
pass
return False

def brute_force(cipher_hex):
charset = string.ascii_lowercase + string.digits # 可选添加更多字符
for length in range(1, 6): # 控制爆破长度
for x_tuple in product(charset, repeat=length):
x = ''.join(x_tuple)
if decrypt(x, cipher_hex):
return # 找到就退出

if __name__ == "__main__":
c = "be6fb6babf792cbbf34883a9356bf73757c92a834efab4bdc196f4476c6715c49efd0bc10b463d94c502045de350c267"
brute_force(c)

输入这个试试baaaaaaaacaaaaacaab

不对这个加上qetxsocool超过了24字符(这条路走不通)

pyc隐写(hint)

https://github.com/AngelKitty/stegosaurus

1747123365152-909bc104-cbf9-4a89-afc7-31e4b47e64c5.png

得到key:huTy1@

1747123404576-eb565172-cd61-4135-a9d9-5bdd3e100b29.png

flag{qetx’s_JETT_1S_S0oo0oo_Wanderfu1!!!}

RE

ipa(校赛)

后缀改成zip然后解压

将exec文件拖入ida反编译

1747206676676-b1a270f2-a557-4686-a42f-2db66f880c12.png

加载的时候没看到最上面的函数(所以说不能只盯着main函数看)

1747206965205-337d5f3e-4a3e-4c64-ad0e-520ead96d7e1.png

数据在src里面

1747207108017-1a3f6a32-9be5-438c-a7e2-8db30fa5da67.png

1
2
3
4
5
6
a='Ios'
miwen=[0x2F,0x3,0x12,0x2E,0x14,0x21,0x2C,0x19,0x16,0x3B,0x1C,0x16,0x16,0x9,0x43,0x3B,0x30,0x3A,0x79,0x1C,0x2C,0x78,0x1C,0x2C,0x0,0x1,0x7,0x2C,0x1D,0x16,0x3A,0x3B,0x1A,0x27,0x8,0xE]
#print(len(miwen))
for i in range(len(miwen)):
b=miwen[i]^ord(a[i%3])
print(chr(b),end='')

1747207305281-7bb2bab9-cc9b-4ca4-900b-35138d365388.png

babyz3

1747036587351-5ade56f1-b762-4ac8-abee-6d5cb7b60f51.png

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int seed; // eax
char s[96]; // [rsp+10h] [rbp-70h] BYREF
int v6; // [rsp+70h] [rbp-10h]
int i_1; // [rsp+78h] [rbp-8h]
int i; // [rsp+7Ch] [rbp-4h]

memset(s, 0, sizeof(s));
v6 = 0;
printf("input:");
__isoc99_scanf("%s", s);
if ( strlen(s) == 20 )
{
seed = time(0LL);
srand(seed);
i_1 = rand() % 100;
for ( i = 0; i < i_1; ++i )
;
if ( *(unsigned __int16 *)s * *(unsigned __int16 *)&s[2] == 342772773
&& *(unsigned __int16 *)s + *(unsigned __int16 *)&s[2] == 39526
&& *(_DWORD *)&s[4] - *(_DWORD *)&s[8] == 1005712381
&& *(unsigned __int16 *)&s[4] + *(unsigned __int16 *)&s[6] == 56269
&& *(unsigned __int16 *)&s[8] - *(unsigned __int16 *)&s[10] == 15092
&& s[4] * s[8] == 10710
&& s[6] * s[10] == 12051
&& s[7] + s[11] == 172
&& *(unsigned __int16 *)&s[12] * *(unsigned __int16 *)&s[14] == 171593250
&& *(unsigned __int16 *)&s[12] + *(unsigned __int16 *)&s[14] == 26219
&& *(unsigned __int16 *)&s[16] * *(unsigned __int16 *)&s[18] == 376306868
&& *(unsigned __int16 *)&s[16] + *(unsigned __int16 *)&s[18] == 40341 )
{
puts("check ok~!");
}
else
{
puts("check failed~!");
}
}
return 1;
}

刚开始还被这个seed迷惑,后来ai分析是混淆代码的

所以直接逆下面的z3就行

主要是中间这块难求,剩下的就是x*y,x+y的简单计算,可手搓也可脚本

1746950053674-d2ade2f6-39d6-4f68-a77b-96fb2230efe5.png得到端序后调整下即可

1746950119674-dea1c885-86a1-4135-bb5d-e48dc8a379a7.png

1746950154580-92cc363e-f357-4f06-bfbe-760120ff3d60.png

1
最后flag{5h12fggtisu8952149ad}

UPX

把标识符改成UPX 脱壳即可

1
2
3
4
a=[0x6D,0x68,0x64,0x69,0x70,0x51,0x75,0x76,0x54,0x35,0x76,0x51,0x65,0x34,0x71,0x51,0x6F,0x35,0x63,0x68,0x62,0x67,0x70,0x62,0x7F,0x79,0x0,0x0,0xB,0x4,0x5,0xE]
for i in range(len(a)):
b=a[i]^a[i%4+28]
print(chr(b),end='')

安卓

1746925862924-ddcf17d4-2524-48a9-a1be-4d6e0d2f93b6.png

一个base64,一个rc4,uname为key

1746928114612-f8174e41-3e47-4f25-84a4-8b801ab5adb3.png

base64加密中的第二个和第三个字符的处理被调换了顺序

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
def decode_custom_base64(s):
# 魔改Base64字符表
BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
table = {char: idx for idx, char in enumerate(BASE64_TABLE)}

bytes_list = []
s = s.rstrip('=') # 去除末尾等号避免干扰

# 每次处理4个字符
for i in range(0, len(s), 4):
chunk = s[i:i + 4].ljust(4, '=') # 补足4字符
c1, c2, c3, c4 = chunk

# 字符转6位值(等号视为0)
v1 = table.get(c1, 0)
v2 = table.get(c2, 0)
v3 = table.get(c3, 0)
v4 = table.get(c4, 0)

# 逆向魔改编码规则计算原始字节
byte1 = (v1 << 2) | ((v3 >> 4) & 0x03)
byte2 = ((v3 & 0x0F) << 4) | ((v2 >> 2) & 0x0F)
byte3 = ((v2 & 0x03) << 6) | v4

# 根据等号位置判断有效字节
if c2 == '=': # 仅1字节有效
bytes_list.append(byte1)
elif c4 == '=': # 2字节有效
bytes_list.append(byte1)
bytes_list.append(byte2)
else: # 3字节有效
bytes_list.append(byte1)
bytes_list.append(byte2)
bytes_list.append(byte3)

return bytes(bytes_list)


# 示例验证
encoded_str = "aFj5YITya42wdRzuZIHwM5Wk"
decoded_bytes = decode_custom_base64(encoded_str)
print(f"Decoded: {decoded_bytes}") # 输出 a3
# j1ya22kn0w4ndr01nd
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
def decrypt(data: bytes, key: bytes) -> bytes:
# 初始化S盒
S = list(range(256))
j = 0
key_len = len(key)

# KSA密钥调度算法(与Java实现完全一致)
for i in range(256):
j = (S[i] + j + key[i % key_len]) % 256
S[i], S[j] = S[j], S[i]

# PRGA伪随机生成算法
i = j = 0
keystream = []
for _ in range(len(data)):
i = (i + 1) % 256
j = (S[i] + j) % 256 # 注意此处与标准RC4不同的加法顺序
S[i], S[j] = S[j], S[i]
keystream.append(S[(S[i] + S[j]) % 256])

# 逆向魔改加密逻辑:加密是加法,解密则用减法
decrypted = bytearray()
for d, k in zip(data, keystream):
decrypted.append((d - k) % 256) # 处理负数自动取模

return bytes(decrypted)


# 测试用例(使用Java代码中的示例数据)
if __name__ == "__main__":
encrypted_data = bytes([
14, 50, 174, 75, 131, 55, 144, 85,
99, 200, 97, 174, 69, 61, 254, 143,
157, 48
])
key = b"j1ya22kn0w4ndr01nd"

result = decrypt(encrypted_data, key)
print("Decrypted hex:", result.hex())
print("Decrypted text:", result.decode('latin-1'))
# andro1nd14d1ffcult

flag{j1ya22kn0w4ndr01nd_andro1nd14d1ffcult}

harre-鸿蒙逆向了解

主要还是熟悉这个hap怎么逆向的

进去后直接就看到一个base64变表加密

1747036391551-833e913b-1e3a-4554-afd8-edaadb09221e.png

1747036402437-f6099d0d-c0b1-4744-9b67-e4a8c0bc4891.png

1747036261199-f5e1e789-eb78-4835-be0f-3a1b09eae051.png

re的本质

??? 不是gm

1
2
a='}detacitsihpos_3b_ot_tub_llik_dn@_thg1f_ot_ton_s1_esrever_f0_ecn3sse_ehT{galf'
print(a[::-1])

Crypto

你们密码手都会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
70
71
from Crypto.Util.number import long_to_bytes, inverse, GCD
from pathlib import Path

def read_public_keys(filename):
with open(filename, "r") as f:
keys = []
for line in f:
N_str, e_str = line.strip().split(",")
keys.append((int(N_str), int(e_str)))
return keys

def read_ciphertexts(filename):
ciphertexts = []
data = Path(filename).read_bytes()

# 密文长度不固定,需要根据 key size 猜长度
# 约为 1024 bits = 128 bytes
i = 0
while i < len(data):
for length in range(128, 150): # 尝试不同长度
chunk = data[i:i+length]
ct = int.from_bytes(chunk, 'big')
if ct.bit_length() > 500: # 粗略过滤无效块
ciphertexts.append(ct)
i += length
break
else:
break
return ciphertexts

def main():
pub_keys = read_public_keys("public_keys.txt")
ciphertexts = read_ciphertexts("ciphertexts.bin")

# Step 1: 找出共享素因子的两组 key
for i in range(len(pub_keys)):
for j in range(i + 1, len(pub_keys)):
N1, _ = pub_keys[i]
N2, _ = pub_keys[j]
p = GCD(N1, N2)
if 1 < p < min(N1, N2):
print(f"Found shared prime p = {p}")
shared_pair = (i, j)
break
else:
continue
break

# Step 2: 获取对应数据
i, j = shared_pair
N1, e = pub_keys[i]
N2, _ = pub_keys[j]
c1 = ciphertexts[i]
c2 = ciphertexts[j]

# Step 3: 分解 N1, N2
p = GCD(N1, N2)
q1 = N1 // p
q2 = N2 // p
phi1 = (p - 1) * (q1 - 1)
d1 = inverse(e, phi1)

# Step 4: 解密
m = pow(c1, d1, N1)
flag = long_to_bytes(m)

print(f"[+] Recovered flag: {flag.decode(errors='ignore')}")

if __name__ == "__main__":
main()

密码是什么可以吃吗

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
import base64

symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
codes = [format(i, '05b').replace('0', 'a').replace('1', 'b') for i in range(32)]
dec_map = {code: sym for sym, code in zip(symbols, codes)} # 创建解码映射


def fix_base32_padding(s):
return s + "=" * ((8 - len(s) % 8) % 8)


def decrypt(ab_text):
# 将密文分割为5字符一组
chunks = [ab_text[i:i + 5] for i in range(0, len(ab_text), 5)]

# 转换为Base32字符
try:
b32_str = ''.join([dec_map[chunk] for chunk in chunks])
except KeyError:
return "包含无效的ab序列"

# 补全padding并解码
b32_str = fix_base32_padding(b32_str)
try:
return base64.b32decode(b32_str).decode('utf-8')
except:
return "解码失败(请检查padding)"


# 要解密的密文
cipher = "abbaabbaabbabbaaabbaaaababbaabbbabbbbabbbbbabaabbaaaaabbbabbbbabbbbaabaababbbaaabaaabbabbbbaabbbbaabbaabbabbbbabbbbaabbabaabbbabbabaababababbbbbbbbaabaababbbaaabaaabbabbbbabaabbaaaaabbbabbbbabbbbaabbabaabbbabbabaababbbbaabbbbaabbaabbabbbbababbbbbabaa"

print(decrypt(cipher))

1747016449411-060cae3b-59a0-4188-9a14-876497a0bca1.png

PWN

mathgame

补上暑假内部赛wp复现

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
from pwn import *
import re

def solve_and_wait():
# 建立连接
p = remote("124.221.156.93", 32946)

try:
# 阶段1:初始化挑战
print("[+] Receiving welcome message...")
welcome_msg = p.recvuntil(b"press the Enter key to start our challenge.", timeout=10)
p.sendline(b'') # 发送回车开始

# 阶段2:处理单次计算
print("\n[+] Receiving math challenge...")
question = p.recvuntil(b'= ', timeout=10).decode().strip()
print(f"Math problem: {question}")

# 计算答案
expr = question.split('=')[0].strip()
expr = expr.replace('×', '*').replace('÷', '/')
try:
answer = str(int(eval(expr)))
except:
answer = "0"

p.sendline(answer.encode())
print(f"Sent answer: {answer}")

# 接收即时响应
response = p.recvline(timeout=5).decode().strip()
print(f"Server reply: {response}")

# 阶段3:保持连接开放
print("\n[+] Connection kept alive for manual interaction")
print("Available commands:")
print(" p.interactive() - 启动交互式shell")
print(" p.recv(n) - 接收n字节数据")
print(" p.send(data) - 发送原始数据")
print(" p.close() - 关闭连接")

# 进入交互模式
p.interactive()

except Exception as e:
print(f"\n[!] Error: {str(e)}")
finally:
if not p.closed:
print("\n[!] Connection left open, remember to close it!")
# 注意:这里故意不自动关闭连接

if __name__ == "__main__":
solve_and_wait()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
time_t seed = time(0LL);
srand(seed);

int v3 = rand() % 10000 + 1;
int v2 = rand() % 10000 + 1;
// 打印题目(可选)
printf("%d * %d = %d\n", v3, v2,v3*v2);

// 构造要发送的命令字符串
char cmd[128];
snprintf(cmd, sizeof(cmd), "nc 124.221.156.93 32914\n%d", v3*v2);

// 执行命令
system(cmd);

return 0;
}


1746936458555-6df028f5-6917-46da-9c47-bf8244e07419.pngflag{598a2e38-cdfa-4b96-a80f-97077df12f3b}

checkin

1746939179739-ba3933a5-9b70-444a-8f8e-70469afd3454.png

1746938913447-a5c9b597-0e58-4095-86f1-64bf28be0f9b.png

  1. 目标值**-2147483645**(十进制)
  2. 对应正数溢出值
    • **int** 范围为 **-2147483648****2147483647**
    • 溢出计算:**目标值 = 目标正数 - 2^32**
    • 解得:**目标正数 = 目标值 + 2^32 = -2147483645 + 4294967296 = 2147483651**
  3. 输入字符串**2147483651**(不以负号开头)。

更新: 2025-06-04 14:38:09
原文: https://www.yuque.com/chaye-apqbl/vsc85q/beb02ytfa81ml8fk


http://example.com/2026/01/19/WP/2025/校赛/
Author
chaye
Posted on
January 19, 2026
Licensed under