BUUCTF-re-page1

easyre

image-20250108211506668

提交

reverse1

跟进Str2,加flag

image-20250108211809481

image-20250108211822919

瞎了,上面还有个如果是o就换成0,改一改提交

{hell0_w0rld}

reverse2

flag:{hacking_for_fun}

但做了替换

image-20250109172202297

flag{hack1ng_fo1_fun}

内涵的软件

DBAPP{49d3c93df25caad81232130f3d2ebfad}

flag{49d3c93df25caad81232130f3d2ebfad}

新年快乐

upx壳,工具脱壳

xor

image-20250111195723660

有个异或逻辑

跟进global

image-20250111195759470

1
2
3
4
5
6
7
8
9
10
11
12
13

enc = [
0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
0x47, 0x32, 0x4F
]

for i in range(len(enc) - 1,1,-1):
enc[i] = chr(enc[i] ^ enc[i - 1])

for i in range(len(enc)):
print(enc[i],end='')

reverse3

跟进Str2,e3nifIH9b_C@n@dH

image-20250111202914772

跟进第一个函数,发现是Base64,下面还对Destination做了处理,我们先还原

1
2
3
4
5

enc = 'e3nifIH9b_C@n@dH'

for i in range(len(enc)):
print(chr(ord(enc[i]) - i),end='')

image-20250111203107855

helloword

Android逆向,先改zip,解压后,jadx打开

image-20250111211542205

不一样的flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
int __cdecl __noreturn main(int argc, const char **argv, const char **envp){
_BYTE v3[29]; // [esp+17h] [ebp-35h] BYREF
int v4; // [esp+34h] [ebp-18h]
int v5; // [esp+38h] [ebp-14h] BYREF
int i; // [esp+3Ch] [ebp-10h]
_BYTE v7[12]; // [esp+40h] [ebp-Ch] BYREF

__main();
v3[26] = 0;
*(_WORD *)&v3[27] = 0;
v4 = 0;
strcpy(v3, "*1111 01000 01010 00010 1111#");
while ( 1 ){
puts("you can choose one action to execute");
puts("1 up");
puts("2 down");
puts("3 left");
printf("4 right\n:");
scanf("%d", &v5);
if ( v5 == 2 ){
++*(_DWORD *)&v3[25];
}
else if ( v5 > 2 ){
if ( v5 == 3 ){
--v4;
}
else {
if ( v5 != 4 )
LABEL_13:
exit(1);
++v4;
}
}
else
{
if ( v5 != 1 )
goto LABEL_13;
--*(_DWORD *)&v3[25];
}
for ( i = 0; i <= 1; ++i )
{
if ( *(_DWORD *)&v3[4 * i + 25] >= 5u )
exit(1);
}
if ( v7[5 * *(_DWORD *)&v3[25] - 41 + v4] == 49 )
exit(1);
if ( v7[5 * *(_DWORD *)&v3[25] - 41 + v4] == '#' )
{
puts("\nok, the order you enter is the flag!");
exit(0);
}
}
}

看着像迷宫

1
2
3
4
5
*1111
01000
01010
00010
1111#

flag{222441144222}

SimpleRev

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
unsigned __int64 Decry(){
char v1; // [rsp+Fh] [rbp-51h]
int v2; // [rsp+10h] [rbp-50h]
int v3; // [rsp+14h] [rbp-4Ch]
int i; // [rsp+18h] [rbp-48h]
int v5; // [rsp+1Ch] [rbp-44h]
char src[8]; // [rsp+20h] [rbp-40h] BYREF
__int64 v7; // [rsp+28h] [rbp-38h]
int v8; // [rsp+30h] [rbp-30h]
__int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF
int v10; // [rsp+50h] [rbp-10h]
unsigned __int64 v11; // [rsp+58h] [rbp-8h]

v11 = __readfsqword(0x28u);
*(_QWORD *)src = 0x534C43444ELL;
v7 = 0LL;
v8 = 0;
v9[0] = 0x776F646168LL;
v9[1] = 0LL;
v10 = 0;
text = (char *)join(key3, v9);
strcpy(key, key1);
strcat(key, src);
v2 = 0;
v3 = 0;
getchar();
v5 = strlen(key);
for ( i = 0; i < v5; ++i )
{
if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
key[i] = key[v3 % v5] + 32;
++v3;
}
printf("Please input your flag:");
while ( 1 )
{
v1 = getchar();
if ( v1 == 10 )
break;
if ( v1 == 32 )
{
++v2;
}
else
{
if ( v1 <= 96 || v1 > 122 )
{
if ( v1 > 64 && v1 <= 90 )
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
++v3;
}
}
else
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
++v3;
}
if ( !(v3 % v5) )
putchar(32);
++v2;
}
}
if ( !strcmp(text, str2) )
puts("Congratulation!\n");
else
puts("Try again!\n");
return __readfsqword(0x28u) ^ v11;
}

直接看到这strcmp(text, str2) 是个校验型的题

text = (char *)join(key3, v9);

key3=kills v9=hadow

text = killshadow

image-20250112143135047

逆向的题一般都是小端序

Str2由v1和key转化而来,先看key

key1:ADSFK

SLCDN

ADSFK+NDCLS = ADSFKNDCLS然后转小写adsfkndcls

输入字符,然后大小写分开处理

然后做Str2 = (input -39 - key[i %len(key)]) % 26 + 97的变换

爆破一下

1
2
3
4
5
6
7
8
9
key = 'adsfkndcls'
enc = 'killshadow'

for i in range(len(enc)):
for j in range(65,128):
if (chr(j) >= 'A' and chr(j) <= 'Z') or (chr(j) >= 'a' and chr(j) <= 'z'):
if (j - 39 - ord(key[i % len(key)]) + 97) % 26 + 97 == ord(enc[i]):
print(chr(j),end='')
break

flag{KLDQCUDFZO}

luck_guy

发现f1:GXY{do_not_

然后发现可疑十六进制处理下就行,注意大小端序

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

# 输入的十六进制字符串
enc = "7F666F6067756369"

def from_small_to_str(enc):
# 将十六进制字符串转换为字节序列
bytes_data = bytes.fromhex(enc)
# 反转字节顺序
reversed_bytes = bytes_data[::-1]
# 将反转后的字节序列转换回十六进制字符串
return str(reversed_bytes, encoding = "utf-8")

res = from_small_to_str(enc)

f1 = 'GXY{do_not_'

print(f1,end='')

for i in range(len(res)):
if i % 2 == 1:
print(chr(ord(res[i]) - 2),end='')
else:
print(chr(ord(res[i]) - 1), end='')

GXY{do_not_hate_me}

然后改GXY为flag就行

Java逆向解密

jadx打开看看

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
package defpackage;

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

/* renamed from: Reverse reason: default package */
/* loaded from: Reverse.class */
public class 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 (char c : arr) {
int result = (c + '@') ^ 32;
Resultlist.add(Integer.valueOf(result));
}
int[] KEY = {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 i : KEY) {
KEYList.add(Integer.valueOf(i));
}
System.out.println("Result:");
if (Resultlist.equals(KEYList)) {
System.out.println("Congratulations!");
} else {
System.err.println("Error!");
}
}
}

直接写解密脚本就行

1
2
3
4
5
6

KEY = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]

for i in range(len(KEY)):
print(chr((KEY[i] ^ 32) - ord('@')),end='')

[BJDCTF2020]JustRE

image-20250114202632497

image-20250114202822258

修改这

image-20250114202813252

image-20250114202918711

刮开有奖

image-20250114202959906

关键:

image-20250114204040344

image-20250114204011433

GPT:4010F0函数

image-20250114204215302

下面是两个Base64函数,对v18进行处理

v7[0]是最小的51+34=85(U)

[51, 67, 69, 72, 74, 78, 83, 90, 97, 103, 110]

J

flag{UJWP1jMp}

[ACTF新生赛2020]easyre

upx壳

image-20250115202930659

不是ACTF而是flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
dic = [
0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75,
0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B,
0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61,
0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57,
0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D,
0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43,
0x42, 0x41, 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2F,
0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25,
0x24, 0x23, 0x20, 0x21, 0x22, 0x00
]

v4 = [0x2A,0x46,0x27,0x22,0x4E,0x2C,0x22,0x28,0x49,0x3F,0x2B,0x40]

for i in v4:
for j in range(len(dic)):
if i == dic[j]:
print(chr(j + 1),end='')
break


U9X_1S_W6@T?

简单注册器

jadx打开

image-20250115205401568

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

enc = 'dd2940c04462b4dd7c450528835cca15'

flag = [ord(enc[i]) for i in range(len(enc))]

flag[2] = flag[2] + flag[3] - 50
flag[4] = flag[2] + flag[5] - 48
flag[30] = flag[31] + flag[9] - 48
flag[14] = flag[27] + flag[28] - 97

for i in range(16):
flag[i],flag[31 - i] = flag[31 - i],flag[i]

for i in range(len(flag)):
print(chr(flag[i]),end='')


59acc538825054c7de4b26440c0999dd

[GWCTF 2019]pyre

在线反编译网站:python反编译 - 在线工具

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
print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128 + 128) % 128
code += num

for i in range(l - 1):
code[i] = code[i] ^ code[i + 1]

print code
code = [
'%1f',
'%12',
'%1d',
'(',
'0',
'4',
'%01',
'%06',
'%14',
'4',
',',
'%1b',
'U',
'?',
'o',
'6',
'*',
':',
'%01',
'D',
';',
'%',
'%13']

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
code = [
'\x1f',
'\x12',
'\x1d',
'(',
'0',
'4',
'\x01',
'\x06',
'\x14',
'4',
',',
'\x1b',
'U',
'?',
'o',
'6',
'*',
':',
'\x01',
'D',
';',
'%',
'\x13']

for i in range(len(code)- 2, -1,-1):
code[i] = chr(ord(code[i]) ^ ord(code[i + 1]))

for i in range(len(code)):
print(chr((ord(code[i]) - i + 128) % 128),end='')

findit

image-20250116213554322

有两个变换,上面那个我看好像没啥用,直接逆下面那个就行

1
2
3
4
5
6
7
8
9
10
11
enc =['p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9',
'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}']

for i in range(len(enc)):
if (enc[i] >= 'A' and enc[i] <= 'Z') or (enc[i] >= 'a' and enc[i] <= 'z'):
enc[i] = chr(ord(enc[i]) + 16)
if ((enc[i] > 'Z' and enc[i] < 'a') or enc[i] >= 'z'):
enc[i] = chr(ord(enc[i]) - 26)

print(enc[i],end='')

[ACTF新生赛2020]rome

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
int func()
{
int result; // eax
int v1[4]; // [esp+14h] [ebp-44h]
unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREF
unsigned __int8 v3; // [esp+25h] [ebp-33h]
unsigned __int8 v4; // [esp+26h] [ebp-32h]
unsigned __int8 v5; // [esp+27h] [ebp-31h]
unsigned __int8 v6; // [esp+28h] [ebp-30h]
int v7; // [esp+29h] [ebp-2Fh]
int v8; // [esp+2Dh] [ebp-2Bh]
int v9; // [esp+31h] [ebp-27h]
int v10; // [esp+35h] [ebp-23h]
unsigned __int8 v11; // [esp+39h] [ebp-1Fh]
char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREF

strcpy(v12, "Qsw3sj_lz4_Ujw@l");
printf("Please input:");
scanf("%s", &v2);
result = v2;
if ( v2 == 'A' )
{
result = v3;
if ( v3 == 'C' )
{
result = v4;
if ( v4 == 'T' )
{
result = v5;
if ( v5 == 'F' )
{
result = v6;
if ( v6 == '{' )
{
result = v11;
if ( v11 == '}' )
{
v1[0] = v7;
v1[1] = v8;
v1[2] = v9;
v1[3] = v10;
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 64 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 90 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 51) % 26 + 65;
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 96 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 122 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 79) % 26 + 97;
++*(_DWORD *)&v12[17];
}
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
result = (unsigned __int8)v12[*(_DWORD *)&v12[17]];
if ( *((_BYTE *)v1 + *(_DWORD *)&v12[17]) != (_BYTE)result )
return result;
++*(_DWORD *)&v12[17];
}
return printf("You are correct!");
}
}
}
}
}
}
return result;
}

v12[17]起到计数作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

enc = 'Qsw3sj_lz4_Ujw@l'

for i in range(len(enc)):
for j in range(128):
t = j
if j <= 90 and j >= 65:
t = (t - 51) % 26 + 65
if j <= 122 and j >= 97:
t = (t - 79) % 26 + 97
if chr(t) == enc[i]:
print(chr(j),end='')
break


[FlareOn4]login

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

<!DOCTYPE Html />
<html>
<head>
<title>FLARE On 2017</title>
</head>
<body>
<input type="text" name="flag" id="flag" value="Enter the flag" />
<input type="button" id="prompt" value="Click to check the flag" />
<script type="text/javascript">
document.getElementById("prompt").onclick = function () {
var flag = document.getElementById("flag").value;
var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
alert("Correct flag!");
} else {
alert("Incorrect flag, rot again");
}
}
</script>
</body>
</html>

ROT13加密

1
2
3
4
5
6
import codecs

encoded_flag = "PyvragFvqrYbtvafNerRnfl@syner-ba.pbz"
decoded_flag = codecs.decode(encoded_flag, 'rot_13')
print(decoded_flag)

rsa

逆向攻防世界CTF系列48-Signin | Matriy’s blog

image-20250118100954953

既然是RSA,pub是公钥,那么另一个应该是密文,可以分解公钥为E和N,还要P和Q

image-20250118095754266

image-20250118101415158

RSA公私钥分解 Exponent、Modulus,Rsa公私钥指数、系数(模数)分解–查错网

n=pq,先转成10进制,然后到网上去分解factordb.com

前面是P后面是Q

image-20250118102036917

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

q = 304008741604601924494328155975272418463
p = 285960468890451637935629440372639283459
e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517

# invmod(a, n) - 求a对于n的模逆,这里逆向加密过程中计算ψ(n)=(p-1)(q-1),对ψ(n)保密,也就是对应根据e*d=1 mod ψ(n),求出d
d = libnum.invmod(e, (p - 1) * (q - 1))

with open('./flag.txt', "rb+") as f:
f = f.read()

c = int.from_bytes(f, byteorder='big')

m = pow(c, d, n)
string = long_to_bytes(m) # 获取m明文,要转成字符串
# print(ex(m)[2:].decode('hex'))
print(string)

flag{decrypt_256}

板子:

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

e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463

phin = (q - 1) * (p - 1)

d = gmpy2.invert(e, phin)

key = rsa.PrivateKey(n, e, int(d), p, q)

# 读取密文
with open("./flag.txt", "rb") as f:
ciphertext = f.read()

# 解密密文
decrypted_message = rsa.decrypt(ciphertext, key)
print(decrypted_message.decode())

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

q = 282164587459512124844245113950593348271
p = 366669102002966856876605669837014229419
e = 65537
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
n = 103461035900816914121390101299049044413950405173712170434161686539878160984549

# invmod(a, n) - 求a对于n的模逆,这里逆向加密过程中计算ψ(n)=(p-1)(q-1),对ψ(n)保密,也就是对应根据e*d=1 mod ψ(n),求出d
d = libnum.invmod(e, (p - 1) * (q - 1))
m = pow(c, d, n)
string = long_to_bytes(m) # 获取m明文,要转成字符串
# print(ex(m)[2:].decode('hex'))
print(string)

[WUSTCTF2020]level1

给了个output文件

image-20250118104338865

直接逆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 初始化列表
numbers = []

# 打开文件并读取数据
with open('output.txt', 'r') as file:
for line in file:
# 将每行的数字转换为整数并添加到列表
numbers.append(int(line.strip()))

for i in range(1, len(numbers) + 1):
if (i & 1) != 0:
print(chr(numbers[i - 1] >> i), end='')
else:
print(chr(numbers[i - 1] // i), end='')

[GUET-CTF2019]re

upx壳

image-20250119095424348

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
flag = ''
flag += chr(166163712 // 1629056)
flag += chr(731332800 // 6771600)
flag += chr(357245568 // 3682944)
flag += chr(1074393000 // 10431000)
flag += chr(489211344 // 3977328)
flag += chr(518971936 // 5138336)
flag += '?'
flag += chr(406741500 // 7532250)
flag += chr(294236496 // 5551632)
flag += chr(177305856 // 3409728)
flag += chr(650683500 // 13013670)
flag += chr(298351053 // 6088797)
flag += chr(386348487 // 7884663)
flag += chr(438258597 // 8944053)
flag += chr(249527520 // 5198490)
flag += chr(445362764 // 4544518)
flag += chr(981182160 // 10115280)
flag += chr(174988800 // 3645600)
flag += chr(493042704 // 9667504)
flag += chr(257493600 // 5364450)
flag += chr(767478780 // 13464540)
flag += chr(312840624 // 5488432)
flag += chr(1404511500 // 14479500)
flag += chr(316139670 // 6451830)
flag += chr(619005024 // 6252576)
flag += chr(372641472 // 7763364)
flag += chr(373693320 // 7327320)
flag += chr(498266640 // 8741520)
flag += chr(452465676 // 8871876)
flag += chr(208422720 // 4086720)
flag += chr(515592000 // 9374400)
flag += chr(719890500 // 5759124)
print(flag)

# flag{e?65421110ba03099a1c039337}

flag{e165421110ba03099a1c039337}

CrackRTF

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
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
DWORD v3; // eax
DWORD v4; // eax
char Str[260]; // [esp+4Ch] [ebp-310h] BYREF
int v7; // [esp+150h] [ebp-20Ch]
char String1[260]; // [esp+154h] [ebp-208h] BYREF
char Destination[260]; // [esp+258h] [ebp-104h] BYREF

memset(Destination, 0, sizeof(Destination));
memset(String1, 0, sizeof(String1));
v7 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", Destination);
if ( strlen(Destination) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
v7 = atoi(Destination);
if ( v7 < 100000 )
ExitProcess(0);
strcat(Destination, "@DBApp");
v3 = strlen(Destination);
sub_40100A((BYTE *)Destination, v3, String1);
if ( !_strcmpi(String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
{
printf("continue...\n\n");
printf("pls input the first passwd(2): ");
memset(Str, 0, sizeof(Str));
scanf("%s", Str);
if ( strlen(Str) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
strcat(Str, Destination);
memset(String1, 0, sizeof(String1));
v4 = strlen(Str);
sub_401019((BYTE *)Str, v4, String1);
if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", String1) )
{
if ( !(unsigned __int8)sub_40100F(Str) )
{
printf("Error!!\n");
ExitProcess(0);
}
printf("bye ~~\n");
}
}
return 0;
}

sub_401019函数实现了对输入数据 pbData 进行 SHA-1 哈希计算,并将计算结果转换为一个十六进制字符串,存储在 lpString1 中。函数内部通过调用 Windows CryptoAPI 来完成加密和哈希操作。

1
2
3
4
5
6
7
8
9
10
11
12
import hashlib
import string

last = '@DBApp'

for i in range(100000,1000000):
enc = str(i) + last
a = hashlib.sha1(enc.encode("utf-8")).hexdigest()
if a.upper() == "6E32D0943418C2C33385BC35A1470250DD8923A9":
print(i)
break

123321@DBApp

image-20250119103522981

下面那个是MD5

image-20250119103704478

万一MD5查不到怎么办思考下,

1
2
3
4
5
6
7
8
9
10
11
12
13
last = "123321@DBApp"

for i in string.printable:
for j in string.printable:
for k in string.printable:
for c in string.printable:
for d in string.printable:
for e in string.printable:
enc = i + j + k + c + d + e + last
a = hashlib.md5(enc.encode("utf")).hexdigest()
if a == "27019e688a4e62a649fd99cadaafdb4e":
print(enc)
break

估了下这个运算要10^12^次,最差的情况是程序需要大约 41.67 天 才能完成所有计算,假设每次 MD5 哈希计算的时间为 1 微秒。

image-20250119104534371

image-20250119104556977

查找资源:首先,它通过FindResourceA函数查找ID为0x65、类型为"AAA"的资源。如果没有找到资源,则返回0

加载资源:如果资源找到了,使用LoadResource将其加载到内存中。

锁定资源:使用LockResource锁定资源,使其可以在程序中访问。

处理资源:调用sub_401005对资源数据进行处理(具体的处理过程不清楚,但可能涉及对数据的修改或计算)。

创建文件并写入数据:使用CreateFileA创建名为"dbapp.rtf"的文件,然后将资源数据写入该文件。

关闭文件:最后,关闭文件句柄。

资源的每一位和密码的每一位循环异或,异或结束之后,生成一个rtf文件

我们的密码一共是6+12=18位

我们现在想要的是前六位的密码,循环异或的话,那么也就是说,资源的前六位与密码的前六位异或的结果就是rtf文件的前六位,我们找来一个rtf文件,看看它的标志位

1
2
3
4
5
6
7
8
rtf = '{\\rtf1' \\需要注意,\r需要转义,变成\\r
A = [0x05, 0x7D, 0x41, 0x15, 0x26, 0x01]
password=''
for i in range(len(rtf)):
x = ord(rtf[i]) ^ A[i]
password+=chr(x)
print(password)

flag{N0_M0re_Free_Bugs}

[WUSTCTF2020]level2

image-20250119143316331

[MRCTF2020]Transform

image-20250119143413620

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import idc
import idaapi

# 设置要读取的地址
address = 0x40F040
num_dwords = 33 # 假设要读取8个 DWORD (32位数) 数据,每个 DWORD 4 字节

# 读取数据,每次读取 4 字节 (DWORD)
data = []
for i in range(num_dwords):
# 获取 4 字节的 DWORD 数据
dword = idc.get_wide_dword(address + i * 4)
data.append(dword) # 将读取的DWORD添加到列表

print("Data at address 0x40F040:", data)

[9, 10, 15, 23, 7, 24, 12, 6, 1, 16, 3, 17, 32, 29, 11, 30, 27, 22, 4, 13, 19, 20, 21, 2, 25, 5, 31, 8, 18, 26, 28, 14, 0]

a,D,e,G

0,1,2,3

3,0,1,2

G,a,D,e

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enc = [
0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79,
0x57, 0x5E, 0x5D, 0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E,
0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E, 0x65, 0x3C, 0x5C, 0x45,
0x6F, 0x62, 0x4D
]

key = [9, 10, 15, 23, 7, 24, 12, 6, 1, 16, 3, 17, 32, 29, 11, 30, 27, 22, 4, 13, 19, 20, 21, 2, 25, 5, 31, 8, 18, 26, 28, 14, 0]

flag = [0 for i in range(33)]

for i in range(len(enc)):
enc[i] ^= key[i]
flag[key[i]] = enc[i]

for i in range(len(enc)):
print(chr(flag[i]), end='')

[2019红帽杯]easyRE

image-20250120102212449

image-20250120103112233

Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ==

image-20250120103101898

flag{Act1ve_Defen5e_Test}

确实找到了…但是这可能不是初衷

如果没找到呢?

1
2
3
4
enc = 'Iodl>Qnb(ocy\x7Fy.i\x7Fd`3w}wek9{iy=~yL@EC'

for i in range(len(enc)):
print(chr(ord(enc[i]) ^ i), end='')

Info:The first four chars are flag

没有有用信息,继续看,跟踪下

image-20250120104425353

image-20250120104401369

可以猜一下,这里长度是25,那堆字符的长度刚好是25,然后做了异或处理

v4异或某个数组是第一位和第四位是fg,可以继续猜,v4异或这个数组后是flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
enc2 = [
0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F,
0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E,
0x72, 0x3C, 0x32, 0x45, 0x5B
]
flag = 'flag'
# for i in range(len(enc2)):
# print(chr(ord(enc2[i]) ^ i))

key = [0 for i in range(4)]

for i in range(4):
key[i] = ord(flag[i]) ^ enc2[i]

print(key)

for i in range(len(enc2)):
print(chr(key[i%4] ^ enc2[i]), end='')

print(len(enc2))

flag{Act1ve_Defen5e_Test}

[ACTF新生赛2020]usualCrypt

直接看到几个可疑的

image-20250120105926571

image-20250120110845191

还有个大小写转换

image-20250120111224986

image-20250120111302572

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

for i in range(len(enc)):
if enc[i] >= 'a' and enc[i] <= 'z':
print(chr(ord(enc[i]) - 32),end='')
elif enc[i] >= 'A' and enc[i] <= 'Z':
print(chr(ord(enc[i]) + 32),end='')
else:
print(enc[i],end='')


print()
key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
key_ord = [ord(i) for i in key]
for i in range(6,15):
key_ord[i],key_ord[i + 10]=key_ord[i + 10],key_ord[i]

for i in key_ord:
print(chr(i),end='')

flag{bAse64_h2s_a_Surprise}

image-20250120112805676

[MRCTF2020]Xor

image-20250120150426705

无法反编译,但是可以看出是xor的逻辑,跟踪到这个

image-20250120150403835

MSAWB~FXZ:J:`tQJ”N@ bpdd}8g

1
2
3
4
enc = 'MSAWB~FXZ:J:`tQJ"N@ bpdd}8g'

for i in range(len(enc)):
print(chr(ord(enc[i]) ^ i), end='')

image-20250120151601101

这样也行

image-20250120151620682

[SUCTF2019]SignIn

image-20250120154256480

image-20250120154339720

看着就像rsa算法,后面的10和16应该是进制

image-20250120155402697

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

q = 282164587459512124844245113950593348271
p = 366669102002966856876605669837014229419
e = 65537
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
n = 103461035900816914121390101299049044413950405173712170434161686539878160984549

# invmod(a, n) - 求a对于n的模逆,这里逆向加密过程中计算ψ(n)=(p-1)(q-1),对ψ(n)保密,也就是对应根据e*d=1 mod ψ(n),求出d
d = libnum.invmod(e, (p - 1) * (q - 1))
m = pow(c, d, n)
string = long_to_bytes(m) # 获取m明文,要转成字符串
# print(ex(m)[2:].decode('hex'))
print(string)

suctf{Pwn_@_hundred_years}

[HDCTF2019]Maze

image-20250120201029299

一上来看到这个,结合题目,猜测这是迷宫题

image-20250120201121468

image-20250120202944655

对这个方法按U取消定义,可以看到这里有个0E8h也就是call,会引发花指令

1
2
3
4
5
6
7
8
main:
xxx
xxx
jz 0xabcd
call(0E8h)
0xabcd:
xxxx
xxxx

这段程序肯定不会执行call但是反编译的时候它不会这么聪明,它是顺序”翻译”的,因此把0xabcd当成了参数翻译

call 0xabcd那后面就乱套了,因此F5失效

不过不是这个call出问题了,而是下面0x2e那边那个,之后对main再p

image-20250120203645492

image-20250120203558793

5和-4是边界值就相当于本来是0-10变成了-4到5了,宽10,那么那个*的总长是70那么7行10列

image-20250120204214407

1
flag{ssaaasaassdddw}

[MRCTF2020]hello_world_go

image-20250120204548250

image-20250120204538309

什么玩意儿,仔细看了下突然看到Flag了

image-20250120210349916