Secret Conversation

image-20210421232210600

附件有两个文件,分别是

main.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
import secrets
from Crypto.Cipher import AES
from binascii import hexlify, unhexlify


previousCt = ""
previousPt = ""
rand_iv = secrets.token_bytes(16)

def pad(plaintext):
	ext = len(plaintext) % 16
	if ext != 0:
		plaintext += "0" * (16 - ext)
	return plaintext

def encrypt(plaintext):
    pt = pad(plaintext)
    if previousPt == "":
        key = pt[:16]
        iv = rand_iv
        c = AES.new(key, AES.MODE_CBC, iv)
    else:
        key = previousPt[:16]
        iv = previousCt[-16:]
        c = AES.new(key, AES.MODE_CBC, iv)
        ct = c.encrypt(pt)
    return ct, iv


# if recive():
#   save(recive())

# if read():
#   previousCt = unhexlify(read())
#   previousPt = decrypt(previousCt)

plaintext = input()
ciphertext, st = encrypt(plaintext)
print(hexlify(ciphertext + st))

# send(hexlify(ciphertext + st))

output.txt

1
2
3
4
Alice: 73d7db011639016953d686a0e1a35bb41500c979211a1cf354bd54f8b38a37a866da4b221f71b2e02f9c08d24908f957
Bob:   52295dc859c7f99e0b711e438fe82009fc3bb14648437adca2ff350a26cdc23c66da4b221f71b2e02f9c08d24908f957
Alice: 89a103a7825bc8e4f6b10062c8a5ff39d224143fd2bc3e7a67085656c054719e66da4b221f71b2e02f9c08d24908f957
Bob:   a3f75a5afb2f2d7dfc0fbfe9d01f17cb8aa192f9da49f009c3d467b908b72b3466da4b221f71b2e02f9c08d24908f957

根据题目描述,已知第一句密文的明文为hello, how are you?

从main.py代码中可以得到以下几点内容

1、第一句加密的key为明文的前16个字符

2、后一句加密使用的key是前一句明文的前16个字符

由此可以写出解密代码如下

 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
from Crypto.Cipher import AES
from binascii import hexlify, unhexlify

previousCt = "hello, how are you?"
previousPt = "73d7db011639016953d686a0e1a35bb41500c979211a1cf354bd54f8b38a37a866da4b221f71b2e02f9c08d24908f957"
rand_iv = bytes.fromhex("66da4b221f71b2e02f9c08d24908f957")


def pad(plaintext):
    ext = len(plaintext) % 16
    if ext != 0:
        plaintext += "0" * (16 - ext)
    return plaintext


def encrypt(plaintext):
    pt = pad(plaintext)
    if previousPt == "":
        key = pt[:16]
        iv = rand_iv
        c = AES.new(key.encode("utf-8"), AES.MODE_CBC, iv)
    else:
        key = previousPt[:16]
        iv = previousCt[-16:]
        c = AES.new(key.encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8"))
    ct = c.encrypt(pt.encode("utf-8"))
    return ct, iv

#
def decrypt(cipertext):
    key = previousPt[:16]
    iv = previousCt[-16:]
    print(key,iv)
    c = AES.new(key, AES.MODE_CBC, iv)
    ct = c.decrypt(cipertext[:-16])
    return ct


# if recive():
#   save(recive())

# if read():
#   previousCt = unhexlify(read())
#   previousPt = decrypt(previousCt)

plaintext = input()
ciphertext, st = encrypt(plaintext)
print(hexlify(ciphertext + st))

# send(hexlify(ciphertext + st))
previousPt = "hello, how are you?".encode("utf-8")
previousCt = unhexlify("73d7db011639016953d686a0e1a35bb41500c979211a1cf354bd54f8b38a37a866da4b221f71b2e02f9c08d24908f957")
previousPt = decrypt(previousCt)
print(previousPt)
previousCt = unhexlify("52295dc859c7f99e0b711e438fe82009fc3bb14648437adca2ff350a26cdc23c66da4b221f71b2e02f9c08d24908f957")
previousPt = decrypt(previousCt)
print(previousPt)
previousCt = unhexlify("89a103a7825bc8e4f6b10062c8a5ff39d224143fd2bc3e7a67085656c054719e66da4b221f71b2e02f9c08d24908f957")
previousPt = decrypt(previousCt)
print(previousPt)
previousCt = unhexlify("a3f75a5afb2f2d7dfc0fbfe9d01f17cb8aa192f9da49f009c3d467b908b72b3466da4b221f71b2e02f9c08d24908f957")
previousPt = decrypt(previousCt)
print(previousPt)
# send(hexlify(ciphertext + st))

最终输出结果

image-20210421232906257

PatienceApp

image-20210421233115114

附件内含一个可执行性文件,在windows下修改后缀后运行,结果如下

image-20210421233310756

拖入IDA,可以看到以下代码,程序在这样的循环体中花费大量时间

image-20210421233410221

此时有多种做法,比如直接修改掉跳转语句。这里不做过多说明,主要想通过这题,演示patch过程

通过IDA定位到长循环的汇编代码如下

image-20210421233907369

其中涉及到两个跳转语句

1
2
.text:004011F0                 jle     short loc_4011D5
.text:00401207                 jge     short loc_4011D0

打算将其修改成相关的跳转语句

比如

1
2
jle=>jge
jge=>gle

选中语句,右键选择Keypatch->Patcher

image-20210421234141396

image-20210421234251711

Assembly中将jle修改成jge即可,同理修改另一处,修改后的结果如下

image-20210421234446556

此时通过下图选项将修改保存

image-20210421234554450

image-20210421234624049

此时成功将我们两次修改保存下来,退出IDA,直接运行程序,直接打印flag

image-20210421235504184

It all starts from the beginning

Level: Hard Category: Reverse Engineering Point: 200 SB-Coin: 5 Challenge Description Can you find the beginning!? File:fina,Main.class

fina内容如下:

1
2
~T\7EWE1W;A5ZTdJ0Vag[ZREaHQEK~

用java反编译工具打开Main.class文件,获取到源码如下

  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
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;

public class Main {
    static String passer="a";
    static int run=0;
    public static void main(String[] args)throws IOException  {
        System.out.println("you shouldn't start from here :)");
    }
    public static void juzbYn(String[] args)throws IOException {

        String Input;
        if (args[0].contains("SBCTF{")){
            Input=args[0];
        }
        else {
            run++;
            if (run==5){
                System.exit(0);
            }
            Input=passer;
        }
        char array[]=passer.toCharArray();
        int j=0;
        for (int i=0;i<array.length;i++){
            if (i%5==0){
                if (j!=0) {
                    System.out.println(i + " : " + array[i]);
                    char a = array[j* 5];
                    System.out.println(a);
                    array[j* 5] = array[j-1];
                    array[j-1] = a;
                }
                j++;
            }
        }
       StringBuilder stringBuilder=new StringBuilder();
        for (char ch:array){
            stringBuilder.append(ch);
        }
        passer = stringBuilder.toString();
        Ft7BEg(new String[]{args[0]});
    }
    public static void b837Lz(String[] args) throws IOException {
        String Input;
        if (args[0].contains("SBCTF{")){
            Input=args[0];
            args[0]="aa";
        }
        else {
            run++;
            if (run==5){
                System.exit(0);
            }
            Input=passer;
        }
        char array[]=passer.toCharArray();
        for (int i=0;i<array.length;i++){
            if (i%5==0){
                array[i]=(char)((array[i]+255)-51*5);
            }
            if (i%2==0){
                array[i]=(char)((array[i]+282)-141*2);
            }
        }
       StringBuilder stringBuilder=new StringBuilder();
        for (char ch:array){
            stringBuilder.append(ch);
        }
        passer = stringBuilder.toString();
        FileWriter myWriter = new FileWriter("fina",true);
        myWriter.write(passer+"\n");
        myWriter.close();
        e66Cbf(new String[]{args[0]});
    }
    public static void e66Cbf(String[] args)throws IOException {
        String Input;
        Random rand = new Random();
        if (args[0].contains("SBCTF{")){
            Input=args[0];
            args[0]="aa";
            run++;
        }
        else {
            run++;
            if (run==5){
                System.exit(0);
            }
            Input=passer;
        }
        char array[]= Input.toCharArray();
        System.out.println(array);
        int i=0;
        for (char b:array){
            array[i]= (char) (b+1);
            i++;
        }
        int randoms[] = new int[6];
        for (i=0;i<5;i++){
            randoms[i]= rand.nextInt(9);
        }
        i=0;
        for (char b:array) {
            array[i] = (char) (b + randoms[i % 6]);
            i++;
        }
       StringBuilder stringBuilder=new StringBuilder();
        for (char ch:array){
            stringBuilder.append(ch);
        }
        passer = stringBuilder.toString();
        juzbYn(new String[]{args[0]});
    }
    public static void Ft7BEg(String[] args)throws IOException {
        String Input;
        if (args[0].contains("SBCTF{")){
            Input=args[0];
        }
        else {
            run++;
            if (run==5){
                System.exit(0);
            }
            Input=passer;
        }
        char array[]=passer.toCharArray();
        for (int i=0;i<array.length;i++){
            if (i%2==0){
                array[i]= (char) (array[i]^2);
            }
        }
        StringBuilder stringBuilder=new StringBuilder();
        for (char ch:array){
            stringBuilder.append(ch);
        }
        passer = stringBuilder.toString();
        b837Lz(new String[]{args[0]});
    }
}

通过运行可以知道函数的运行顺序是e66Cbf->juzbYn->Ft7BEg->b837Lz

然后代码阅读可以知道一下几点内容:

  • Flag开头是SBCTF{
  • e66Cbf:随机生成一个长度为6的数组randoms,将用户输入后的Flag,先每个字符都+1,再根据索引i,每个字符加上randoms[i%6],逆过程可以根据Flag开头6位的变动可以推出实际的randoms
  • juzbYn:将上一步的结果的前6位,分别与索引5,10,15,20,25的字符交换位置。逆过程是同样的。
  • Ft7BEg:偶数索引的字符与2做异或。逆过程是同样的
  • b837Lz:将结果输出到文件中。函数内的循环是一个烟雾弹

基于以上几点内容,写出以下脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
prefix = "SBCTF{"
result = "~T\\7EWE1W;A5ZTdJ0Vag[ZREaHQEK~"
rlist = list(result)
for i in range(len(rlist)):
    if i % 2 == 0:
        rlist[i] = chr(ord(rlist[i]) ^ 2)
j = 0
for i in range(len(rlist)):
    if i % 5 == 0:
        if j != 0:
            rlist[i], rlist[j - 1] = rlist[j - 1], rlist[i]
        j += 1
randoms = []
for i in range(6):
    randoms.append(ord(rlist[i]) - ord(prefix[i]))
    rlist[i] = prefix[i]
for i in range(6, len(rlist)):
    rlist[i]=chr(ord(rlist[i])-randoms[i%6])
print("".join(rlist))

运行后的结果如下:

image-20210422233522826