AVALON 强网杯 2019 强网杯 JustRe write up

强网杯 JustRe write up

环境配置

系统 : Linux kali 4.15.0-kali2-amd64 \ win10 64bit
程序 : JustRe.exe
要求 : 输入口令
使用工具 :x64dbg / ida pro / peid

开始分析

拿信息

二进制文件下载后使用file拿信息:

➜  playground file task_JustRe3.tar.gz 
task_JustRe3.tar.gz: gzip compressed data, last modified: Wed May 22 01:39:26 2019, from Unix

发现是压缩包,解压之:

tar -xzvf task_JustRe3.tar.gz

解压出来一个exe文件,使用peid拿信息:

Microsoft Visual Studio .NET 2005 -- 2008 -> Microsoft Corporation

再用peid的密码学插件查看信息,点击拓展信息 -> 插件 -> krypto analyzer:

DES [long] :: 00001F74 :: 00403174
    The reference is above.

静态分析

ida载入程序,主流程如下:

int sub_401BD0()
{
  int result; // eax
  char *my_str; // [esp+4h] [ebp-68h]
  int savedregs; // [esp+6Ch] [ebp+0h]

  puts("      #                        ######         ");
  puts("      # #    #  ####  #####    #     # ###### ");
  puts("      # #    # #        #      #     # #      ");
  puts("      # #    #  ####    #      ######  #####  ");
  puts("#     # #    #      #   #      #   #   #      ");
  puts("#     # #    # #    #   #      #    #  #      ");
  puts(" #####   ####   ####    #      #     # ###### ");
  sub_401CE0("%s", &my_str);
  if ( sub_401610(&my_str, &savedregs) && sub_4018A0(&my_str) )
  {
    puts("congrats!");
    sub_401CA0("flag{%.26s}\n\n", &my_str);
    result = 0;
  }
  else
  {
    puts("sorry..");
    result = 0;
  }
  return result;
}

程序对我们输入的字符串(长度为26)进行检查,如果都合格则输出flag。

第一个检查点

12345678AB作为输入,使用x64dbg调试程序,发现第一个检查点的关键代码如下:

00401728 | 0FBECE                   | movsx ecx,dh                                  |
0040172B | 66:0F6EC1                | movd xmm0,ecx                                 |
0040172F | 66:0F60C0                | punpcklbw xmm0,xmm0                           |
00401733 | 66:0F61C0                | punpcklwd xmm0,xmm0                           |
00401737 | 66:0F70C0 00             | pshufd xmm0,xmm0,0                            | 覆盖到xmm0 全是AB AB AB...
0040173C | 0F2945 E0                | movaps xmmword ptr ss:[ebp-20],xmm0           | 覆盖栈
00401740 | 85F6                     | test esi,esi                                  |
00401742 | 0F84 49010000            | je justre.401891                              |
00401748 | 33F6                     | xor esi,esi                                   |
0040174A | 833D C4534000 02         | cmp dword ptr ds:[4053C4],2                   |
00401751 | 0F8C B4000000            | jl justre.40180B                              |
00401757 | 66:0F6E45 E0             | movd xmm0,dword ptr ss:[ebp-20]               | 修改成为 AB AB AB AB
0040175C | BE 10000000              | mov esi,10                                    |
00401761 | 0F281D 40434000          | movaps xmm3,xmmword ptr ds:[404340]           |
00401768 | 66:0F3831E0              | pmovzxbd xmm4,xmm0                            | 骚操作,xmm4变成000000AB000000AB000000AB000000AB
0040176D | 66:0F384025 80434000     | pmulld xmm4,xmmword ptr ds:[404380]           | xmm4 == ABABABAB...
00401776 | 0F1005 18504000          | movups xmm0,xmmword ptr ds:[405018]           | 载入第一行到寄存器
0040177D | 0F28CC                   | movaps xmm1,xmm4                              |
00401780 | 0F10D3                   | movups xmm2,xmm3                              |
00401783 | 66:0FFEC8                | paddd xmm1,xmm0                               | 1+0
00401787 | 66:0FFED5                | paddd xmm2,xmm5                               | 2+5
0040178B | 0F1005 28504000          | movups xmm0,xmmword ptr ds:[405028]           | 载入第二行到寄存器
00401792 | 66:0FEFD1                | pxor xmm2,xmm1                                |
00401796 | 0F28CC                   | movaps xmm1,xmm4                              |
00401799 | 0F1115 18504000          | movups xmmword ptr ds:[405018],xmm2           |
004017A0 | 0F2815 50434000          | movaps xmm2,xmmword ptr ds:[404350]           |
004017A7 | 66:0FFEC8                | paddd xmm1,xmm0                               |
004017AB | 0F1005 38504000          | movups xmm0,xmmword ptr ds:[405038]           | 载入第三行到寄存器
004017B2 | 66:0FFED3                | paddd xmm2,xmm3                               |
004017B6 | 66:0FFED5                | paddd xmm2,xmm5                               |
004017BA | 66:0FEFD1                | pxor xmm2,xmm1                                |
004017BE | 0F28CC                   | movaps xmm1,xmm4                              |
004017C1 | 0F1115 28504000          | movups xmmword ptr ds:[405028],xmm2           |
004017C8 | 0F2815 60434000          | movaps xmm2,xmmword ptr ds:[404360]           |
004017CF | 66:0FFEC8                | paddd xmm1,xmm0                               |
004017D3 | 0F1005 48504000          | movups xmm0,xmmword ptr ds:[405048]           | 载入第四行到寄存器
004017DA | 66:0FFED3                | paddd xmm2,xmm3                               |
004017DE | 66:0FFED5                | paddd xmm2,xmm5                               |
004017E2 | 66:0FFEE0                | paddd xmm4,xmm0                               |
004017E6 | 66:0FEFD1                | pxor xmm2,xmm1                                |
004017EA | 0F280D 70434000          | movaps xmm1,xmmword ptr ds:[404370]           |
004017F1 | 66:0FFECB                | paddd xmm1,xmm3                               |
004017F5 | 66:0FFECD                | paddd xmm1,xmm5                               |
004017F9 | 66:0FEFCC                | pxor xmm1,xmm4                                |
004017FD | 0F1115 38504000          | movups xmmword ptr ds:[405038],xmm2           |
00401804 | 0F110D 48504000          | movups xmmword ptr ds:[405048],xmm1           |
0040180B | 0FB6CE                   | movzx ecx,dh                                  |
0040180E | 69F9 01010101            | imul edi,ecx,1010101                          | edi:"LdrpInitializeProcess"
00401814 | 8B14B5 18504000          | mov edx,dword ptr ds:[esi*4+405018]           | edx = a[esi]
0040181B | 8D0C06                   | lea ecx,dword ptr ds:[esi+eax]                | ecx = esi + 0x12345678
0040181E | 03D7                     | add edx,edi                                   | edi:"LdrpInitializeProcess"
00401820 | 33D1                     | xor edx,ecx                                   | edx += 0xABABABAB
00401822 | 8914B5 18504000          | mov dword ptr ds:[esi*4+405018],edx           |
00401829 | 46                       | inc esi                                       |
0040182A | 83FE 18                  | cmp esi,18                                    |
0040182D | 7C E5                    | jl justre.401814                              |
0040182F | 33C9                     | xor ecx,ecx                                   |
00401831 | 8A81 18504000            | mov al,byte ptr ds:[ecx+405018]               |
00401837 | 3A81 48414000            | cmp al,byte ptr ds:[ecx+404148]               |
0040183D | 75 4F                    | jne justre.40188E                             |
0040183F | 41                       | inc ecx                                       |
00401840 | 83F9 60                  | cmp ecx,60                                    | 60:'`'
00401843 | 7C EC                    | jl justre.401831                              |

大概就是将输入转化为 x = 0x12345678 , y = 0xAB ,接着f(x,y,0x405018) == 0x404148这个等式成立才可以通过检查。

solved

这里我对上面的xmm寄存器操作指令纠结了半天,后天终于是想到可以用z3对下面半部分比较简单的代码求解试试:

from z3 import *

def double_data(x):
    a = x
    x = a << 32 
    x += a
    return x
'''
def dd_data(x):
    a = double_data(x)
    x = a << 64
    x += a
    return x

def pull_data(x):
    a = x
    x = a << 24 | a << 16 | a << 8 | a
    return x

'''
p1 = BitVec('x',32)#0x12345678
p2 = BitVec('y',32)#0xAB

#assert (dd_data(p1)) == 0x12345678123456781234567812345678L
#assert (pull_data(p2)) == 0xabababab

solver = Solver()

a = [ 0x244D9725,  0x248D9C22,  0x00111073,  0x09610EFE,  0xFBED535A,  0x00186782,  0x8B51356B,  0xFE58F3E8 ]
res = [ 0x24448840,  0x24848D4C,  0x000001FC,  0x0F50006A,  0x1C244411,  0x000F58E8,  0x8D406A00,  0x02482484 ]

for esi in range(0x10,0x18):
#  edx = a[esi-0x10]
#  ecx = esi + p1
#  edx += pull_data(p2) 
#  edx ^= ecx
    edx = (a[esi-0x10] + p2) ^ (esi + p1)
    solver.add(edx & 0xFFFFFFFF == res[esi-0x10])

if ( solver.check() == sat ):
    print 'ok'
    print solver.model()

运行结果:

➜  playground python test2.py
ok
[y = 320017171, x = 321135208]
➜  playground python         
Python 2.7.14+ (default, Mar 13 2018, 15:23:44) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print hex(321135208)
0x13242268
>>> print hex(320017171)
0x13131313
>>> exit()
➜  playground 1324226813

所以这里,第一部分的flag为1324226813

绕过反调试

之前列出的代码在做完对比之后还没完,之后的代码比较奇怪:

.text:0040184C                 rdtsc
.text:0040184E                 pop     esi
.text:0040184F                 pop     edi
.text:00401850                 cmp     edx, edi
.text:00401852                 ja      short loc_401860
.text:00401854                 sub     eax, esi
.text:00401856                 mov     [ebp-8], eax
.text:00401859                 cmp     eax, 0FFFFFFh
.text:0040185E                 jb      short loc_401864
.text:00401860
.text:00401860 loc_401860:                             ; CODE XREF: sub_401610+242↑j
.text:00401860                 xor     eax, eax
.text:00401862                 mov     [eax], eax

很容易调试的时候走到反调试区域loc_401860,这里我发现执行到loc_401860就直接set ip跳入正常流程了。

SMC 我 改 我 自 己

接下来的代码:

.text:00401865                 push    0               ; lpNumberOfBytesWritten
.text:00401867                 push    60h             ; nSize
.text:00401869                 push    offset xmmword_405018 ; lpBuffer
.text:0040186E                 push    offset sub_4018A0 ; lpBaseAddress
.text:00401873                 call    ds:GetCurrentProcess
.text:00401879                 push    eax             ; hProcess
.text:0040187A                 call    ds:WriteProcessMemory

程序在patch自己,这里完成修改后,发现sub_4018A0函数可以查看伪c代码了。

第二个检查点

修复函数

这里解释一下修复和查看函数sub_4018A0伪代码的过程,将函数头部分识别成数据的内容指定成代码(按c),然后右击Create Function就可以了。

solved

通过对比算法结构和之前拿到的信息,基本上确认就是一个三重des加密了,我们用搜索到的3des源码试试加密的结果和调试的结果是否一致,一致则意味着可以直接解密:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define DES_LONG unsigned long
#define LEN_OF_KEY 24

#define ITERATIONS 16

#define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
                         l|=((DES_LONG)(*((c)++)))<< 8L, \
                         l|=((DES_LONG)(*((c)++)))<<16L, \
                         l|=((DES_LONG)(*((c)++)))<<24L)


#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))

#define ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))

#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
        u=R^s[S  ]; \
        t=R^s[S+1]

#define D_ENCRYPT(LL,R,S) {\
        LOAD_DATA_tmp(R,S,u,t,E0,E1); \
        t=ROTATE(t,4); \
        LL^=\
                DES_SPtrans[0][(u>> 2L)&0x3f]^ \
                DES_SPtrans[2][(u>>10L)&0x3f]^ \
                DES_SPtrans[4][(u>>18L)&0x3f]^ \
                DES_SPtrans[6][(u>>26L)&0x3f]^ \
                DES_SPtrans[1][(t>> 2L)&0x3f]^ \
                DES_SPtrans[3][(t>>10L)&0x3f]^ \
                DES_SPtrans[5][(t>>18L)&0x3f]^ \
                DES_SPtrans[7][(t>>26L)&0x3f]; }

#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
        (b)^=(t),\
        (a)^=((t)<<(n)))

#define IP(l,r) \
        { \
        register DES_LONG tt; \
        PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
        PERM_OP(l,r,tt,16,0x0000ffffL); \
        PERM_OP(r,l,tt, 2,0x33333333L); \
        PERM_OP(l,r,tt, 8,0x00ff00ffL); \
        PERM_OP(r,l,tt, 1,0x55555555L); \
        }

#define FP(l,r) \
        { \
        register DES_LONG tt; \
        PERM_OP(l,r,tt, 1,0x55555555L); \
        PERM_OP(r,l,tt, 8,0x00ff00ffL); \
        PERM_OP(l,r,tt, 2,0x33333333L); \
        PERM_OP(r,l,tt,16,0x0000ffffL); \
        PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
        }

extern const DES_LONG DES_SPtrans[8][64];         


#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
        (a)=(a)^(t)^(t>>(16-(n))))

static const DES_LONG des_skb[8][64] = {
    {
     /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
     0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L,
     0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L,
     0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L,
     0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L,
     0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L,
     0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L,
     0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L,
     0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L,
     0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L,
     0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L,
     0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L,
     0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L,
     0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L,
     0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L,
     0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L,
     0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L,
     },
    {
     /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
     0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L,
     0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L,
     0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L,
     0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L,
     0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L,
     0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L,
     0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L,
     0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L,
     0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L,
     0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L,
     0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L,
     0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L,
     0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L,
     0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L,
     0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L,
     0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L,
     },
    {
     /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
     0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L,
     0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L,
     0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L,
     0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L,
     0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L,
     0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L,
     0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L,
     0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L,
     0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L,
     0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L,
     0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L,
     0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L,
     0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L,
     0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L,
     0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L,
     0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L,
     },
    {
     /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
     0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L,
     0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L,
     0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L,
     0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L,
     0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L,
     0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L,
     0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L,
     0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L,
     0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L,
     0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L,
     0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L,
     0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L,
     0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L,
     0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L,
     0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L,
     0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L,
     },
    {
     /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
     0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L,
     0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L,
     0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L,
     0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L,
     0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L,
     0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L,
     0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L,
     0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L,
     0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L,
     0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L,
     0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L,
     0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L,
     0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L,
     0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L,
     0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L,
     0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L,
     },
    {
     /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
     0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L,
     0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L,
     0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L,
     0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L,
     0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L,
     0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L,
     0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L,
     0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L,
     0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L,
     0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L,
     0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L,
     0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L,
     0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L,
     0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L,
     0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L,
     0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L,
     },
    {
     /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
     0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L,
     0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L,
     0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L,
     0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L,
     0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L,
     0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L,
     0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L,
     0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L,
     0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L,
     0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L,
     0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L,
     0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L,
     0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L,
     0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L,
     0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L,
     0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L,
     },
    {
     /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
     0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L,
     0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L,
     0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L,
     0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L,
     0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L,
     0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L,
     0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L,
     0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L,
     0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L,
     0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L,
     0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L,
     0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L,
     0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L,
     0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L,
     0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L,
     0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L,
     }
};

const DES_LONG DES_SPtrans[8][64] = {
    {
        /* nibble 0 */
        0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
        0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
        0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
        0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
        0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
        0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
        0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
        0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
        0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
        0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
        0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
        0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
        0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
        0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
        0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
        0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
    },
    {
        /* nibble 1 */
        0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
        0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
        0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
        0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
        0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
        0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
        0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
        0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
        0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
        0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
        0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
        0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
        0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
        0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
        0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
        0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
    },
    {
        /* nibble 2 */
        0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
        0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
        0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
        0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
        0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
        0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
        0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
        0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
        0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
        0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
        0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
        0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
        0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
        0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
        0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
        0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
    },
    {
        /* nibble 3 */
        0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
        0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
        0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
        0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
        0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
        0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
        0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
        0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
        0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
        0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
        0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
        0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
        0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
        0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
        0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
        0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
    },
    {
        /* nibble 4 */
        0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
        0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
        0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
        0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
        0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
        0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
        0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
        0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
        0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
        0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
        0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
        0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
        0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
        0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
        0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
        0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
    },
    {
        /* nibble 5 */
        0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
        0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
        0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
        0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
        0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
        0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
        0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
        0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
        0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
        0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
        0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
        0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
        0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
        0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
        0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
        0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
    },
    {
        /* nibble 6 */
        0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
        0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
        0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
        0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
        0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
        0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
        0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
        0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
        0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
        0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
        0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
        0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
        0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
        0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
        0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
        0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
    },
    {
        /* nibble 7 */
        0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
        0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
        0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
        0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
        0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
        0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
        0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
        0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
        0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
        0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
        0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
        0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
        0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
        0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
        0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
        0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
    }
};


typedef unsigned char DES_cblock[8];
typedef /* const */ unsigned char const_DES_cblock[8];


typedef struct DES_ks {
    union {
        DES_cblock cblock;
        /*
         * make sure things are correct size on machines with 8 byte longs
         */
        DES_LONG deslong[2];
    } ks[16];
} DES_key_schedule;


# define DES_ENCRYPT     1
# define DES_DECRYPT     0



void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
                      DES_key_schedule *ks1, DES_key_schedule *ks2,
                      DES_key_schedule *ks3, int enc);


void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc);

void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc);

void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
                  DES_key_schedule *ks2, DES_key_schedule *ks3);
void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
                  DES_key_schedule *ks2, DES_key_schedule *ks3);

void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);

void re_set(int* my_cipher_text)
{
    my_cipher_text[0] = 0xE6A97C50;
    my_cipher_text[1] = 0xFACE0987;
    my_cipher_text[2] = 0xCF0DD520;
    my_cipher_text[3] = 0x6C97BB90;
}

/************************************************************************
 * 3DES-ECB加密方式
 * 8字节密钥,加密内容8位补齐,补齐方式为:PKCS7。
 *
 * file: des3_func.c.c
 * gcc -Wall -O2 -o des3_func des3_func.c 
 *
 * @author  Edward
 *
 ************************************************************************/
int main(int argc, char *argv[])
{
    int i = 0;
    int len = 0;
    int nlen = 0;
    int klen = 0;

    char ch = '\0';
    //char *k = "ABCDEFGHABCDEFGHABCDEFGH";
    char *k = "AFSAFCEDYCXCXACNDFKDCQXC";

    //char *data = "123456789ABCDEFG";  /* 原始明文 */
    char *data = "AAAAAAAAAAAAAAAA";  /* 原始明文 */

    unsigned char key[LEN_OF_KEY];
    unsigned char src[64] = {0};
    unsigned char out[64] = {0};
    unsigned char tmp[64] = {0};

    unsigned char block[8] = {0};
    DES_key_schedule ks1, ks2, ks3;

    /* 设置密码表 */
    klen = strlen(k);
    memcpy(key, k, klen);
    memset(key + klen, 0x00, LEN_OF_KEY - klen); 


    memcpy(block, key, sizeof(block));
    DES_set_key_unchecked((const_DES_cblock *)block, &ks1);

    memcpy(block, key + 8, sizeof(block));
    DES_set_key_unchecked((const_DES_cblock *)block, &ks2);

    memcpy(block, key + 16, sizeof(block));
    DES_set_key_unchecked((const_DES_cblock *)block, &ks3);

    nlen = strlen(data);
    memcpy(src, data, nlen);

    //len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;
    len = (nlen / 8 + 1) * 8;

    ch = 8 - nlen % 8;
    //memset(src + nlen, ch, (8 - nlen % 8) % 8);
     memset(src + nlen, ch, (8 - nlen % 8));

    for (i = 0; i < len; i += 8) {
        DES_ecb3_encrypt((const_DES_cblock *)(src + i), (DES_cblock *)(out + i), &ks1, &ks2, &ks3, DES_ENCRYPT);
    }

    printf("encrypted Hex:");
    for (i = 0; i < len; i++) {
        printf("%02X" , *(out + i));
    }
    printf("\n");

    re_set((int*)out); //安排

    for (i = 0; i < len; i += 8) {
        DES_ecb3_encrypt((const_DES_cblock *)(out + i), (DES_cblock *)(tmp + i), &ks1, &ks2, &ks3, DES_DECRYPT);
    }

    printf("decrypted Hex:");
    for (i = 0; i < len; i++) {
        printf("%02X", *(tmp + i));
    }
    printf("\n");
    printf("decrypted Bin:");
    for (i = 0; i < len; i++) {
        printf("%c", *(tmp + i));
    }
    printf("\n");

    return 0;
}


void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
{
    static const int shifts2[16] =
        { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
    register DES_LONG c, d, t, s, t2;
    register const unsigned char *in;
    register DES_LONG *k;
    register int i;


    k = &schedule->ks->deslong[0];
    in = &(*key)[0];

    c2l(in, c);
    c2l(in, d);

    /*
     * do PC1 in 47 simple operations :-) Thanks to John Fletcher
     * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-)
     */
    PERM_OP(d, c, t, 4, 0x0f0f0f0fL);
    HPERM_OP(c, t, -2, 0xcccc0000L);
    HPERM_OP(d, t, -2, 0xcccc0000L);
    PERM_OP(d, c, t, 1, 0x55555555L);
    PERM_OP(c, d, t, 8, 0x00ff00ffL);
    PERM_OP(d, c, t, 1, 0x55555555L);
    d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) |
         ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L));
    c &= 0x0fffffffL;

    for (i = 0; i < ITERATIONS; i++) {
        if (shifts2[i]) {
            c = ((c >> 2L) | (c << 26L));
            d = ((d >> 2L) | (d << 26L));
        } else {
            c = ((c >> 1L) | (c << 27L));
            d = ((d >> 1L) | (d << 27L));
        }
        c &= 0x0fffffffL;
        d &= 0x0fffffffL;
        /*
         * could be a few less shifts but I am to lazy at this point in time
         * to investigate
         */
        s = des_skb[0][(c) & 0x3f] |
            des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] |
            des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
            des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) |
                       ((c >> 22L) & 0x38)];
        t = des_skb[4][(d) & 0x3f] |
            des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] |
            des_skb[6][(d >> 15L) & 0x3f] |
            des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];

        /* table contained 0213 4657 */
        t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
        *(k++) = ROTATE(t2, 30) & 0xffffffffL;

        t2 = ((s >> 16L) | (t & 0xffff0000L));
        *(k++) = ROTATE(t2, 26) & 0xffffffffL;
    }
}


void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
                      DES_key_schedule *ks1, DES_key_schedule *ks2,
                      DES_key_schedule *ks3, int enc)
{
    register DES_LONG l0, l1;
    DES_LONG ll[2];
    const unsigned char *in = &(*input)[0];
    unsigned char *out = &(*output)[0];

    c2l(in, l0);
    c2l(in, l1);
    ll[0] = l0;
    ll[1] = l1;

    if (enc)
        DES_encrypt3(ll, ks1, ks2, ks3);
    else
        DES_decrypt3(ll, ks1, ks2, ks3);
    l0 = ll[0];
    l1 = ll[1];
    l2c(l0, out);
    l2c(l1, out);
}


void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
{
    register DES_LONG l, r, t, u;
    /*
#ifdef DES_PTR
    register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
#endif
#ifndef DES_UNROLL

#endif*/
    register int i;
    register DES_LONG *s;

    r = data[0];
    l = data[1];

    IP(r, l);
    /*
     * Things have been modified so that the initial rotate is done outside
     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
     * 1 bit to the right. One perl script later and things have a 5% speed
     * up on a sparc2. Thanks to Richard Outerbridge
     * <71755.204@CompuServe.COM> for pointing this out.
     */
    /* clear the top bits on machines with 8byte longs */
    /* shift left by 2 */
    r = ROTATE(r, 29) & 0xffffffffL;
    l = ROTATE(l, 29) & 0xffffffffL;

    s = ks->ks->deslong;
    /*
     * I don't know if it is worth the effort of loop unrolling the inner
     * loop
     */
    if (enc) {

        for (i = 0; i < 32; i += 4) {
            D_ENCRYPT(l, r, i + 0); /* 1 */
            D_ENCRYPT(r, l, i + 2); /* 2 */
        }
    } else {

        for (i = 30; i > 0; i -= 4) {
            D_ENCRYPT(l, r, i - 0); /* 16 */
            D_ENCRYPT(r, l, i - 2); /* 15 */
        }
    }

    /* rotate and clear the top bits on machines with 8byte longs */
    l = ROTATE(l, 3) & 0xffffffffL;
    r = ROTATE(r, 3) & 0xffffffffL;

    FP(r, l);
    data[0] = l;
    data[1] = r;
    l = r = t = u = 0;
}

void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
{
    register DES_LONG l, r, t, u;
    /*
#ifdef DES_PTR
    register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
#endif
#ifndef DES_UNROLL
    register int i;
#endif*/
    register int i;
    register DES_LONG *s;

    r = data[0];
    l = data[1];

    /*
     * Things have been modified so that the initial rotate is done outside
     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
     * 1 bit to the right. One perl script later and things have a 5% speed
     * up on a sparc2. Thanks to Richard Outerbridge
     * <71755.204@CompuServe.COM> for pointing this out.
     */
    /* clear the top bits on machines with 8byte longs */
    r = ROTATE(r, 29) & 0xffffffffL;
    l = ROTATE(l, 29) & 0xffffffffL;

    s = ks->ks->deslong;
    /*
     * I don't know if it is worth the effort of loop unrolling the inner
     * loop
     */
    if (enc) {

        for (i = 0; i < 32; i += 4) {
            D_ENCRYPT(l, r, i + 0); /* 1 */
            D_ENCRYPT(r, l, i + 2); /* 2 */
        }

    } else {

        for (i = 30; i > 0; i -= 4) {
            D_ENCRYPT(l, r, i - 0); /* 16 */
            D_ENCRYPT(r, l, i - 2); /* 15 */
        }

    }
    /* rotate and clear the top bits on machines with 8byte longs */
    data[0] = ROTATE(l, 3) & 0xffffffffL;
    data[1] = ROTATE(r, 3) & 0xffffffffL;
    l = r = t = u = 0;
}

void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
                  DES_key_schedule *ks2, DES_key_schedule *ks3)
{
    register DES_LONG l, r;

    l = data[0];
    r = data[1];
    IP(l, r);
    data[0] = l;
    data[1] = r;
    DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
    DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
    DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
    l = data[0];
    r = data[1];
    FP(r, l);
    data[0] = l;
    data[1] = r;
}

void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
                  DES_key_schedule *ks2, DES_key_schedule *ks3)
{
    register DES_LONG l, r;

    l = data[0];
    r = data[1];
    IP(l, r);
    data[0] = l;
    data[1] = r;
    DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
    DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
    DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
    l = data[0];
    r = data[1];
    FP(r, l);
    data[0] = l;
    data[1] = r;
}

运行结果:

➜  playground ./test              
encrypted Hex:EC56716ADAE47B98EC56716ADAE47B989090F6B07BA6A4E8
decrypted Hex:306463633530396136663735383439620808080808080808
decrypted Bin:0dcc509a6f75849b

夺旗成功

使用得到的两段flag作为输入:

C:\Users\Vincent_GU\Downloads\re\2019 qwb>JustRe.exe
      #                        ######
      # #    #  ####  #####    #     # ######
      # #    # #        #      #     # #
      # #    #  ####    #      ######  #####
#     # #    #      #   #      #   #   #
#     # #    # #    #   #      #    #  #
 #####   ####   ####    #      #     # ######
13242268130dcc509a6f75849b
congrats!
flag{13242268130dcc509a6f75849b}

参考链接

  1. [原创]看雪ctf秋季赛 第二题 利用z3解方程 https://bbs.pediy.com/thread-222342.htm
  2. 网鼎杯CTF Martricks http://dreamcracker.today/2019/04/29/%e7%bd%91%e9%bc%8e%e6%9d%afctf-martricks/
  3. 3DES加解密 C语言 https://www.cnblogs.com/one–way/archive/2016/07/05/5643771.html