# some_RE 题目

# ez_z3

一道来自 NSSCTF 举办的逆向专题比赛 round#x 的题目

(NSSCTF 和 NKCTF 时间重复了 两边都在看题 = =)

image-20230331170435294

在 IDA 中看很明显看到加了壳 直接脱 UPX 不行 魔改了 010 中查看发现就是改了字节头的加壳 直接在 010 中搜索 XYU1 改成 UPX! 就行了

image-20230331171858307

成功脱壳后在 IDA 中看到主程序 2 次输入 其中在第二个输入后越过循环看到一个需要 z3 解的函数

image-20230331173707760

直接解就行了

上脚本

from z3 import *
a1 = [BitVec('x%d' % i, 32) for i in range(20)]
s = Solver()
for i in range(20):
    s.add(a1[i] < 127)  # 添加约束条件①因为输入的肯定是可见字符
    s.add(a1[i] >= 32)
s.add(
    20 * a1[19] * 19 * a1[18]
    + 14 * a1[13]
    + 13 * a1[12]
    + 11 * a1[10] * 10 * a1[9]
    + 30 * a1[5]
    + 5 * a1[4]
    + a1[0]
+ 2 * a1[1]
- 3 * a1[2]
- 4 * a1[3]
- 7 * a1[6]
+ 8 * a1[7]
- 9 * a1[8]
- 12 * a1[11]
- 16 * a1[15] * 15 * a1[14]
- 17 * a1[16]
- 18 * a1[17] == 2582239)
s.add(
    20 * a1[19] * 19 * a1[18]
    + 14 * a1[13]
    + 13 * a1[12]
    + 11 * a1[10] * 10 * a1[9]
    + 30 * a1[5]
    - 7 * a1[6]
    + 8 * a1[7]
    - 9 * a1[8]
    + 5 * a1[4]
    + 3 * a1[2]
    + 2 * a1[1] * a1[0]
    - 4 * a1[3]
    - 12 * a1[11]
    - 16 * a1[15] * 15 * a1[14]
    - (18 * a1[17]
       + 17 * a1[16]) == 2602741)
s.add(19 * a1[18]
     + 18 * a1[17]
     + 14 * a1[13] * 13 * a1[12]
     + 12 * a1[11] * 11 * a1[10]
     + 9 * a1[8]
     + 7 * a1[6] * 30 * a1[5]
     + a1[0]
     - 2 * a1[1]
     - 4 * a1[3] * 3 * a1[2]
     - 5 * a1[4]
     + 8 * a1[7]
     - 10 * a1[9]
     - 15 * a1[14]
     - 17 * a1[16] * 16 * a1[15]
     - 20 * a1[19] == 2668123)
s.add(20 * a1[19] * 19 * a1[18]
     + 14 * a1[13]
     + (13 * a1[12] + 11 * a1[10] - 12 * a1[11]) * 10 * a1[9]
     + 30 * a1[5]
     + 5 * a1[4]
     + a1[0]
     + 2 * a1[1]
     - 3 * a1[2]
     - 4 * a1[3]
     - 7 * a1[6]
     + 8 * a1[7]
     - 9 * a1[8]
     - 16 * a1[15] * 15 * a1[14]
     - 17 * a1[16]
     - 18 * a1[17] == 2520193)
s.add(
    18 * a1[17]
    + 17 * a1[16]
    + 15 * a1[14]
    + 13 * a1[12] * 12 * a1[11]
    + 10 * a1[9]
    + 9 * a1[8] * 8 * a1[7]
    + 3 * a1[2] * 2 * a1[1] * a1[0]
    - 4 * a1[3]
    - 5 * a1[4]
    - 30 * a1[5]
    - 7 * a1[6]
    - 11 * a1[10]
    - 14 * a1[13]
    - 16 * a1[15]
    - 19 * a1[18]
    - 20 * a1[19] == 8904587)
s.add(
    18 * a1[17]
    + 7 * a1[6] * 30 * a1[5] * 5 * a1[4]
    + 4 * a1[3]
    + 8 * a1[7]
    + a1[0]
- 2 * a1[1]
- 3 * a1[2]
- 9 * a1[8]
- 11 * a1[10] * 10 * a1[9]
- 16 * a1[15] * (13 * a1[12] + 12 * a1[11] - 14 * a1[13] - 15 * a1[14])
- 17 * a1[16]
- 19 * a1[18]
- 20 * a1[19] == 1227620874)
s.add(20 * a1[19] * 19 * a1[18]
     + 17 * a1[16]
     + 14 * a1[13]
     + 13 * a1[12]
     + 12 * a1[11] * 11 * a1[10] * 10 * a1[9]
     + 7 * a1[6] * 30 * a1[5]
     + 5 * a1[4]
     + 3 * a1[2]
     + a1[0]
     + 2 * a1[1]
     + 4 * a1[3]
     + 8 * a1[7]
     - 9 * a1[8]
     - 16 * a1[15] * 15 * a1[14]
     - 18 * a1[17] == 1836606059)
s.add(
    20 * a1[19] * 19 * a1[18]
    + 16 * a1[15] * 15 * a1[14]
    + 14 * a1[13]
    + 13 * a1[12]
    + 12 * a1[11]
    + 7 * a1[6] * 30 * a1[5]
    + 5 * a1[4]
    + 2 * a1[1] * a1[0]
    - 3 * a1[2]
    + 4 * a1[3]
    + 8 * a1[7]
    - 9 * a1[8]
    - 10 * a1[9]
    - 11 * a1[10]
    - 17 * a1[16]
    - 18 * a1[17] == 8720560)
s.add(20 * a1[19] * 19 * a1[18]
     + 14 * a1[13]
     + 13 * a1[12]
     + 11 * a1[10] * (10 * a1[9] + 30 * a1[5] + 5 * a1[4] + 4 * a1[3] - 7 * a1[6] + 8 * a1[7] - 9 * a1[8])
     + a1[0]
     + 2 * a1[1]
     - 3 * a1[2]
     - 12 * a1[11]
     - (16 * a1[15] - 17 * a1[16] - 18 * a1[17]) * 15 * a1[14] == 11387045)
s.add(
    20 * a1[19] * 19 * a1[18]
    + 16 * a1[15] * 15 * a1[14]
    + 14 * a1[13]
    + 11 * a1[10] * 10 * a1[9]
    + 9 * a1[8]
    + 3 * a1[2]
    + a1[0]
- 2 * a1[1]
+ 4 * a1[3]
- 5 * a1[4]
- 30 * a1[5]
- 7 * a1[6]
+ 8 * a1[7]
- 12 * a1[11]
- 13 * a1[12]
- 17 * a1[16]
- 18 * a1[17] == 7660269)
s.add(20 * a1[19] * 19 * a1[18]
     + 14 * a1[13]
     + 13 * a1[12]
     + 11 * a1[10] * 10 * a1[9]
     - 12 * a1[11]
     + a1[0]
     + 2 * a1[1]
     - (4 * a1[3] * 3 * a1[2]
      - 5 * a1[4]
      - 30 * a1[5])
     - 7 * a1[6]
     + 8 * a1[7]
     - 9 * a1[8]
     - 16 * a1[15] * 15 * a1[14]
     - 17 * a1[16]
     - 18 * a1[17] == 2461883)
s.add(
    14 * a1[13]
    + 11 * a1[10] * 10 * a1[9]
    + 9 * a1[8] * 8 * a1[7]
    + 7 * a1[6]
    + 2 * a1[1] * a1[0]
    - 4 * a1[3] * 3 * a1[2]
    - 5 * a1[4]
    - 30 * a1[5]
    - 12 * a1[11]
    - 13 * a1[12]
    - 15 * a1[14]
    - 17 * a1[16] * 16 * a1[15]
    - 18 * a1[17]
    - 19 * a1[18]
    - 20 * a1[19] == -966296)
s.add(
14 * a1[13]
     + 13 * a1[12]
     + (11 * a1[10] * 10 * a1[9] + 30 * a1[5] + 5 * a1[4] + 3 * a1[2] + 4 * a1[3] - 7 * a1[6] + 8 * a1[7] - 9 * a1[8])
     * 2
     * a1[1]
     + a1[0]
     - 12 * a1[11]
     - 15 * a1[14]
     - 16 * a1[15]
     - 17 * a1[16]
     - 18 * a1[17]
     - 20 * a1[19] * 19 * a1[18] == 254500223
    )
s.add(
16 * a1[15] * 15 * a1[14]
     + 14 * a1[13]
     + 11 * a1[10] * 10 * a1[9]
     + 7 * a1[6] * 30 * a1[5]
     + a1[0]
     - 2 * a1[1]
     - 3 * a1[2]
     - 5 * a1[4] * 4 * a1[3]
     + 8 * a1[7]
     - 9 * a1[8]
     - 12 * a1[11]
     - 13 * a1[12]
     - 17 * a1[16]
     - 18 * a1[17]
     - 19 * a1[18]
     - 20 * a1[19] == 6022286
    )
s.add(
18 * a1[17]
     + 16 * a1[15]
     - 17 * a1[16]
     + 14 * a1[13]
     + 12 * a1[11]
     + 11 * a1[10] * 10 * a1[9]
     + 30 * a1[5]
     + 5 * a1[4]
     + 4 * a1[3] * 3 * a1[2]
     + 2 * a1[1] * a1[0]
     - 9 * a1[8] * 8 * a1[7] * 7 * a1[6]
     - 13 * a1[12]
     - 15 * a1[14]
     - 19 * a1[18]
     - 20 * a1[19] == -636956022
    )
s.add(
20 * a1[19] * 19 * a1[18]
     + 13 * a1[12]
     + 12 * a1[11]
     + 11 * a1[10] * 10 * a1[9]
     + 7 * a1[6]
     + 30 * a1[5]
     + 5 * a1[4]
     + 3 * a1[2] * 2 * a1[1] * a1[0]
     - 4 * a1[3]
     - 9 * a1[8] * 8 * a1[7]
     - 14 * a1[13]
     - 15 * a1[14]
     - 16 * a1[15]
     - 17 * a1[16]
     - 18 * a1[17] == 10631829
)
s.add(
20 * a1[19] * 19 * a1[18]
     + 16 * a1[15]
     - 17 * a1[16]
     - 18 * a1[17]
     + 15 * a1[14] * 14 * a1[13]
     + 13 * a1[12]
     + 11 * a1[10] * 10 * a1[9]
     - 12 * a1[11]
     + 7 * a1[6]
     + (4 * a1[3] - 5 * a1[4] - 30 * a1[5]) * 3 * a1[2]
     + a1[0]
     + 2 * a1[1]
     + 8 * a1[7]
     - 9 * a1[8] == 6191333
)
s.add(
14 * a1[13]
     + 10 * a1[9] * 9 * a1[8] * 8 * a1[7]
     + 5 * a1[4]
     + 4 * a1[3] * 3 * a1[2]
     + 2 * a1[1] * a1[0]
     - 7 * a1[6] * 30 * a1[5]
     - 11 * a1[10]
     - 13 * a1[12] * 12 * a1[11]
     - 16 * a1[15] * 15 * a1[14]
     - 18 * a1[17] * 17 * a1[16]
     - 20 * a1[19] * 19 * a1[18] == 890415359
)
s.add(
20 * a1[19]
     + 19 * a1[18]
     + 18 * a1[17]
     + 16 * a1[15]
     - 17 * a1[16]
     + 12 * a1[11]
     + 11 * a1[10]
     + 10 * a1[9]
     + 9 * a1[8]
     + 30 * a1[5]
     + a1[0]
     + 4 * a1[3] * 3 * a1[2] * 2 * a1[1]
     - 5 * a1[4]
     - 7 * a1[6]
     + 8 * a1[7]
     - 13 * a1[12]
     - 14 * a1[13]
     - 15 * a1[14] == 23493664
)
s.add(
20 * a1[19] * 19 * a1[18]
     + 13 * a1[12]
     + 12 * a1[11]
     + 10 * a1[9]
     + 3 * a1[2] * 2 * a1[1]
     + a1[0]
     - 4 * a1[3]
     - 5 * a1[4]
     + 8 * a1[7] * 7 * a1[6] * 30 * a1[5]
     - 9 * a1[8]
     - 11 * a1[10]
     - 14 * a1[13]
     - 16 * a1[15] * 15 * a1[14]
     - 17 * a1[16]
     - 18 * a1[17] == 1967260144
)
flag = []
strflag = ''
if s.check() == sat:  # 检测是否有解
    result = s.model()
    for i in a1:  # 因为最后得出的是等式,先遍历 a1,把 a1 的每个依次赋给 i
        flag.append(result[i])  # 然后找到每个 a1 对应的解,附加到空列表的后面
    print(flag)
else:
    print('无解')
#得 [104, 97, 104, 97, 104, 97, 116, 104, 105, 115, 105, 115, 102, 97, 99, 107, 102, 108, 97, 103]

注意 Z3 约束求解器 - 初始化序列时选择正确的格式 比如这里就是 int 型序列

得第二次输入为 [104, 97, 104, 97, 104, 97, 116, 104, 105, 115, 105, 115, 102, 97, 99, 107, 102, 108, 97, 103]

image-20230331183241670

z3 的数据在这里用到,又 weneed 比较数据已知 可求出数组 tempp

cp=[0x00001207, 0x00004CA0, 0x00004F21, 0x00000039, 0x0001A523, 0x0000023A, 0x00000926, 0x00004CA7, 0x00006560, 0x00000036, 0x0001A99B, 0x00004CA8, 0x0001BBE0, 0x00003705, 0x00000926, 0x000077D3, 0x00009A98, 0x0000657B, 0x00000018, 0x00000B11]
z33=[104, 97, 104, 97, 104, 97, 116, 104, 105, 115, 105, 115, 102, 97, 99, 107, 102, 108, 97, 103]
for i in range(len(cp)):
    cp[i]^=z33[len(cp)-i-1]
print(cp)

cp (比较数据) 与倒过来的 z33 数据异或得 tempp 数组 [4704, 19649, 20301, 95, 107848, 601, 2375, 19649, 25875, 95, 109032, 19649, 113544, 14193, 2375, 30651, 39673, 25875, 121, 2937]

image-20230331203202364

image-20230331203306709

最后的关键在这一步函数,又因为函数的第二个参数是 int 数组 somenum 已知,tempp 已知,直接爆破 flag

C 语言爆破脚本如下

#include <stdio.h>
#include <string.h>
int baopo(int a1, int a2){
    {
  unsigned int v3; 
  v3 = 1;
  while ( a2 )
  {
    if ( (a2 & 1) != 0 )
      v3 *= a1;
    a1 = a1 * a1 % 1000;
    a2 >>= 2;
  }
  return v3;
}
}
int main(){
    unsigned int somenum[20] = {
    0x00000007, 0x00000007, 0x00000007, 0x00000009, 0x00000005, 0x00000006, 0x00000007, 0x00000007, 
    0x00000007, 0x00000009, 0x00000007, 0x00000007, 0x00000005, 0x00000007, 0x00000007, 0x00000007, 
    0x00000005, 0x00000007, 0x00000009, 0x00000007
};
int cp[20]={4704, 19649, 20301, 95, 107848, 601, 2375, 19649, 25875, 95, 109032, 19649, 113544, 14193, 2375, 30651, 39673, 25875, 121, 2937};
    int flag[20]={0};
    for(int i=0; i<20; i++){
        
        while (baopo(flag[i],somenum[i]) != cp[i])
        {
         flag[i]++;
        };
        printf("%d ",flag[i]);
    
}
}

运行结果 84 49 101 95 122 51 95 49 115 95 118 49 114 57 95 51 97 115 121 33

转字符即为 flag: T1e_z3_1s_v1r9_3asy! 把 flag 用给定的格式包起来提交就行了

# ctfshow 愚人杯 RE

image-20230402190420667

除了一道抽象谜语题 其他挺简单的 我都能一眼丁真

# easy_pyc

先解 pyc 发现很简单 不过就 114514 有点迷惑性 其实可以直接去掉 我直接 z3 解出

image-20230401162939514

# 脚本及 flag

from z3 import *
code = [    0x16,   0x1d,   0x1e,   0x1a,   0x18,   0x09,   0xff,   0xd0,  0x2c,   0x03,  0x02,  0x14,  0x38,  0x6d,  0x01,  0x43,  0x44,  0xbd,  0xf7,
    0x2a,    0x0d,   0xda,   0xf9,   0x1c,   0x26,  0x35,   0x27,   0xda,   0xd4,   0xd1,   0x0b,   0xc7,   0xc7,   0x1a,   0x90,   0x44,   0xa1]
l = len(code)
codec=[]
a1 = [BitVec('x%d' % i, 32) for i in range(l)]
s = Solver()
for i in range(l):
    num = ((a1[i] + i) )
    codec.append(num)
for i in range((l - 4) + 1):
    codec[i] = codec[i] ^ codec[i + 1]
for i in range(l):
    s.add(codec[i]==code[i])
flag = []
if s.check() == sat:  # 检测是否有解
    result = s.model()
    for i in a1:  # 因为最后得出的是等式,先遍历 a1,把 a1 的每个依次赋给 i
        flag.append(result[i])  # 然后找到每个 a1 对应的解,附加到空列表的后面
    print(flag)
else:
    print('无解')
str=''
flag=[99, 116, 102, 115, 104, 111, 119, 123, 74, 117, 115, 116, 95, 70, 48, 48, 108, 39, 115, 95, 68, 64, 121, 95, 82, 51, 95, 67, 104, 51, 99, 107, 45, 105, 110, 33, 125]
for i in range(len(flag)):
    str+=chr(flag[i])
print(str)

ctfshow

# easy_cc

32 位 IDA 打开 程序逻辑很简单 直接解 上脚本

eee=[0x08,0x11,0x1f,0x42,0x5a,0x5c,0x1c,0x1e,0x1a,0x52,0x6d,0x41,0x0e,0x3a,0x1e,0x5e,0x5d,0x57,0x34,0x02,0x16,0x5e,0x56,0x12,0x16]
key='key123'
key=list(key)
v17=[]
for i in range(len(eee)):
    v17.append((eee[i])^ord(key[i%len(key)]))
print(v17)
strr=''
for i in range(len(v17)):
    strr+=chr(v17[i])
print(strr)

ctfshow

# babyre

动调

image-20230402160324387

提取的比较数据 [0x79, 0x8F, 0xAA, 0xEE, 0x69, 0x6A, 0x65, 0x53, 0x2B, 0xEE, 0x7B, 0x80, 0x9B, 0xD7, 0x7D, 0x9B, 0xD0, 0x2B, 0xE8, 0x71, 0x7E, 0x9B, 0xBD, 0xFD]

image-20230402161233601

看看加密函数

image-20230402161428887

我直接开爆 (其实是 z3)

from z3 import *
temp = [BitVec('x%d' % i, 8) for i in range(24)]  # 初始化序列
s = Solver()  # 创建约束求解器
cp=[0x79, 0x8F, 0xAA, 0xEE, 0x69, 0x6A, 0x65, 0x53, 0x2B, 0xEE, 0x7B, 0x80, 0x9B, 0xD7, 0x7D, 0x9B, 0xD0, 0x2B, 0xE8, 0x71, 0x7E, 0x9B, 0xBD, 0xFD]
l=len(cp)
sum=0
for i in range(l):
    sum=0
    for j in range(l):
        sum=temp[j]+sum
    temp[i]=sum
for i in range(l):
    s.add(cp[i]==temp[i])
print(s.check())
flag=[]
result = s.model()
print(result)
-----------------get flag-------------------
flag=[99,116,102,115,104,111,119,123,104,97,118,101, 95,49,95,102,117,110,95,100,97,121,125]
strr=''
for i in range(len(flag)):
    strr+=chr(flag[i])
print(strr)
#ctfshow{have_1_fun_day}

弗拉格为 ctfshow

# easy_re

image-20230402170213727

32 位直接 IDA

image-20230402170739439

逻辑也很清晰 问题是获取 key 可以通过爆破?后面怎么办 做不来摆烂了 等 wp

# not_a_like

NKCTF 一道题,和前面的 ez_z3 类似 魔改的 UPX 壳,不同的是它不是修改了区段头名字而是直接抹去了

image-20230401150936440

和正常的一对比就能补充上头部了

image-20230401152446898

(其实位置没有规定的那么固定)

直接解 upx 然后放进 IDA 中看 可判断为 py 打包 (也可从程序的大小很大看出)

直接 python pyinstxtractor.py not_a_like.exe (这里其实警告说是 python3.8 我是 3.10 但发现没影响后面)

直接找在线工具解密 pyc 得以下 py 脚本

#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.8
import libnum
import base64
import hashlib
from ctypes import *
def encrypt(text):
    data_xor_iv = bytearray()
    sbox = []
    j = 0
    x = y = k = 0
    key = '911dcd09ad021d68780e3efed1aa8549'
    for i in range(256):
        sbox.append(i)
    for i in range(256):
        j = j + sbox[i] + ord(key[i % len(key)]) & 255
        sbox[i] = sbox[j]
        sbox[j] = sbox[i]
    for idx in text:
        x = x + 1 & 255
        y = y + sbox[x] & 255
        sbox[x] = sbox[y]
        sbox[y] = sbox[x]
        k = sbox[sbox[x] + sbox[y] & 255]
        data_xor_iv.append(idx ^ k)
    return data_xor_iv
if __name__ == '__main__':
    flag = input('%e8%af%b7%e8%be%93%e5%85%a5flag> ')
    pub_key = [
        0x1B6A7561D99E6FC35BA3C241159424698BF3CAC017CFCE8BB325CC9AF9CBCBDB3997B08D922C8705FC3EEAEF50D60ADAB2757A7204715483A1D612502970595358BCFE9CD11C98CAD293EB921D777F4F910905D79CDCA5C1EC1FBA5DA74DB165F82BBE29EA0B2E597860FC6D2C51C12D46BF11AFA5018496DDFC3474B10B4457L,
        0x6C8E1CC5B384DE3B3316C22CF72D9895406298E172B5F4D890BDC04889BB43CD4892689DE701C84ED68B4CBC7193926BCCB0A4F259D2E752FAEF3CD590A793F120D15424AEB3CD53F5D59B5D41D699694ABF4F01532F0F1CE127B07958FB874982E757EF97643335376790BC990CEE9D7F0D05DA90AD62084C88BFA9C9BEB683L]
    m = libnum.s2n(flag)
    c = str(pow(m, pub_key[0], pub_key[1]))
    q = b'EeJWrgtF+5ue9MRiq7drUAFPtrLATlBZMBW2CdWHRN73Hek7DPVIYDHtMIAfTcYiEV87W7poChqpyUXYI3+/zf5yyDOyE9ARLfa5qilXggu60lmQzFqvFv+1uOaeI2hs2wx+QZtxqGZzC0VCVWvbTQ52nA2UdUtnk8VezRMPMfmf7rOqPxDTv/aacLnI3RdLG2TbT52qtN4+naejI7Xe8HLOL765OZKdDBERKwd5ARQ3UL6YPbuOKOQahIFddnIX6rZ7dTNqCUDOjfJbMdrzJVDNjmNlkLNtYFo7M65Wfwj6PV5vvtT33FsmH50/YLEasnlCiJujYOgi2KCdf5msz1dPEvrXDDL6Csnjo+6m/44RzlluzcqMS5ZJFdrHEh68LIqtu+HCO+69Dyq4e22APq8wgN9kU6R8kikXSn/Ej0N/jOvomFCbkHskRl8xP1KgWFW0SMVDlaDCM4EKG812VgDWgSYOUnVhVpz65uOtg4Z8PrPI+BW4398dQYhD24D9EIPgvtmhNrHiEHouB46ElTGQgZBhtn6y9tL1sw=='
    v = encrypt(base64.b64encode(c.encode('utf-8')))
    v = base64.b64encode(v)
    if v == q:
        print('You are right!')
        input('')
    else:
        print('winer winer winnie dinner')
        print('Do you think the encryption and decryption are the same?')

分析逻辑知输入 flag 后先是 RSA 加密,再 base64 加密,再 RC4 加密,再 base64 加密 又比较数据已知直接找脚本或工具解就行了

附上一个包括了所有解密的完整脚本

import base64, gmpy2, libnum
def continuedFra(x, y):
    cf = []
    while y:
        cf.append(x // y)
        x, y = y, x % y
    return cf
def gradualFra(cf):
    numerator = 0
    denominator = 1
    for x in cf[::-1]:
        numerator, denominator = denominator, x * denominator + numerator
    return numerator, denominator
def solve_pq(a, b, c):
    par = gmpy2.isqrt(b * b - 4 * a * c)
    return (-b + par) // (2 * a), (-b - par) // (2 * a)
def getGradualFra(cf):
    gf = []
    for i in range(1, len(cf) + 1):
        gf.append(gradualFra(cf[:i]))
    return gf
def wienerAttack(e, n):
    cf = continuedFra(e, n)
    gf = getGradualFra(cf)
    for d, k in gf:
        if k == 0: continue
        if (e * d - 1) % k != 0:
            continue
        phi = (e * d - 1) // k
        p, q = solve_pq(1, n - phi + 1, n)
        if p * q == n:
            return d
c = bytearray()
pub_key = [
    19252067118061066631831653736874168743759225404757996498452383337816071866700225650384181012362739758314516273574942119597579042209488383895276825193118297972030907899188520426741919737573230050112614350868516818112742663713344658825493377512886311960823584992531185444207705213109184076273376878524090762327,
    76230002233243117494160925838103007078059987783012242668154928419914737829063294895922280964326704163760912076151634681903538211391318232043295054505369037037489356790665952040424073700340441976087746298068796807069622346676856605244662923296325332812844754859450419515772460413762564695491785275009170060931]
q = b'EeJWrgtF+5ue9MRiq7drUAFPtrLATlBZMBW2CdWHRN73Hek7DPVIYDHtMIAfTcYiEV87W7poChqpyUXYI3+/zf5yyDOyE9ARLfa5qilXggu60lmQzFqvFv+1uOaeI2hs2wx+QZtxqGZzC0VCVWvbTQ52nA2UdUtnk8VezRMPMfmf7rOqPxDTv/aacLnI3RdLG2TbT52qtN4+naejI7Xe8HLOL765OZKdDBERKwd5ARQ3UL6YPbuOKOQahIFddnIX6rZ7dTNqCUDOjfJbMdrzJVDNjmNlkLNtYFo7M65Wfwj6PV5vvtT33FsmH50/YLEasnlCiJujYOgi2KCdf5msz1dPEvrXDDL6Csnjo+6m/44RzlluzcqMS5ZJFdrHEh68LIqtu+HCO+69Dyq4e22APq8wgN9kU6R8kikXSn/Ej0N/jOvomFCbkHskRl8xP1KgWFW0SMVDlaDCM4EKG812VgDWgSYOUnVhVpz65uOtg4Z8PrPI+BW4398dQYhD24D9EIPgvtmhNrHiEHouB46ElTGQgZBhtn6y9tL1sw=='
e = pub_key[0]
n = pub_key[1]
# 恢复 c
v = base64.b64decode(q)
data_xor_iv = bytearray()
sbox = []
j = 0
x = y = k = 0
key = '911dcd09ad021d68780e3efed1aa8549'
for i in range(256):
    sbox.append(i)
for i in range(256):
    j = j + sbox[i] + ord(key[(i % len(key))]) & 255
    sbox[i], sbox[j] = sbox[j], sbox[i]
for idx in v:
    x = x + 1 & 255
    y = y + sbox[x] & 255
    sbox[x], sbox[y] = sbox[y], sbox[x]
    k = sbox[(sbox[x] + sbox[y] & 255)]
    c.append(idx ^ k)
c = int(base64.b64decode(bytes(c)))
# 维纳攻击
d = wienerAttack(e, n)
m = pow(c, d, n)
print(libnum.n2s(m).decode())
更新于 阅读次数