跳转至

Crypto Decrypt It easy

1 题目

  • 题目描述: 找到字符串在随机化之前.
  • 题目附件: 下载附件
$ unzip 25a3b5ca44524966bc029b262028e345.zip
Archive:  25a3b5ca44524966bc029b262028e345.zip
  inflating: ecrypt1.bin             
  inflating: rnd                     
  inflating: readme.txt

$ cat readme.txt 
$ ./rnd crypt1.png ecrypt1.bin

$ file rnd
rnd: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=6a1443272dd530117d3c63884e195120a845c499, stripped

从上文可知,加密文件ecrypt1.bin由图片crypt1.png经可执行程序rnd加密生成

2 可执行程序rnd

Ghidra打开:

void entry(void)

{
  __libc_start_main(FUN_08048514);
  do {
                    /* WARNING: Do nothing block with infinite loop */
  } while( true );
}



undefined4 FUN_08048514(int param_1,int param_2)

{
  undefined4 uVar1;
  uint __seed;
  FILE *__stream;
  FILE *__stream_00;
  size_t sVar2;
  int iVar3;
  byte local_11 [13];

  if (param_1 < 3) {
    uVar1 = 1;
  }
  else {
    __seed = time((time_t *)0x0);
    srand(__seed);
    __stream = fopen(*(char **)(param_2 + 4),"rb");
    __stream_00 = fopen(*(char **)(param_2 + 8),"wb");
    while( true ) {
      sVar2 = fread(local_11,1,1,__stream);
      if (sVar2 != 1) break;
      iVar3 = rand();
      local_11[0] = local_11[0] ^ (byte)iVar3;
      fwrite(local_11,1,1,__stream_00);
    }
    fclose(__stream);
    fclose(__stream_00);
    uVar1 = 0;
  }
  return uVar1;
}

函数FUN_08048514打开两个文件,__stream,__stream_00,从__stream读取一个字节,与随机数iVar3异或后写入__stream_00 其中随机数使用种子__seed = time((time_t *)0x0) https://blogs.univ-poitiers.fr/e-laize/2014/12/08/seccon-2014-quals-crypto-decrypt-it/

$ stat ecrypt1.bin
  File: « ecrypt1.bin »
  Size: 45989       Blocks: 96         IO Block: 4096   fichier
Device: 801h/2049d  Inode: 49544       Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ phoenix)   Gid: ( 1000/ phoenix)
Access: 2014-11-22 15:46:36.000000000 +0100
Modify: 2014-11-22 15:46:30.000000000 +0100
Change: 2014-12-07 00:53:58.000000000 +0100

$ stat --printf=%Y  ecrypt1.bin 
1416667590

3 exp

#include<iostream>
#include<cstdlib>
#include <time.h>
using namespace std;

int main() {
    FILE *__stream;
    FILE *__stream_00;
    int sVar2;
    int local_11[11];
    int iVar3;

    // https://blogs.univ-poitiers.fr/e-laize/2014/12/08/seccon-2014-quals-crypto-decrypt-it/
    //srand(time(NULL));
    srand(1416667590);  

    __stream = fopen("ecrypt1.bin","rb");
    __stream_00 = fopen("crypt1.png","wb");
    while( 1 ) {
        sVar2 = fread(local_11,1,1,__stream);
        if (sVar2 != 1) break;
        iVar3 = rand();
        //local_11[0] = local_11[0] ^ (iVar3 & 0xff);
        //local_11[0] = local_11[0] ^ iVar3;
        local_11[0] = local_11[0] ^ (iVar3 & 0xff);
        fwrite(local_11,1,1,__stream_00);
    }
    fclose(__stream);
    fclose(__stream_00);

  return 0;
}

如果想编出32位的程序,需要安装东西。

$ sudo apt-get install build-essential module-assistant  
$ sudo apt-get install gcc-multilib g++-multilib  

g++ -m32 exp.cpp

4 png

图片内容如下:

N = pq
C = M(M + B) mod N

N = B8AE199365      B = FFEEE      C = 8D5051562B
N = B86E78C811      B = FFFEE      C = 5FFA0AC1A2
N = 7BD4071E55      B = FEFEF      C = 6008DDF867

~~爆破:~~

data = [(0xB8AE199365, 0xFFEEE, 0x8D5051562B), (0xB86E78C811, 0xFFFEE, 0x5FFA0AC1A2), (0x7BD4071E55, 0xFEFEF, 0x6008DDF867)] 
R = []
cnt = 1
for (N, B, C) in data:
    print(cnt)
    cnt = cnt +1
    for M in range(N):
        if C == M*(M+B) % N:
           print("M = ", M)
           R.append(M)

http://factordb.com/分解N得:

0xB8AE199365 = 868019 · 913799
0xB86E78C811 = 875543 · 904727
0X7BD4071E55 = 597263 · 890459
爆破:
data = [(868019, 913799, 0xFFEEE, 0x8D5051562B), (875543, 904727, 0xFFFEE, 0x5FFA0AC1A2), (597263, 890459, 0xFEFEF, 0x6008DDF867)] 
R = []
cnt = 1
for (p, q, B, C) in data:
    print(cnt)
    cnt = cnt +1
    for M in range(p):
        if C%p == (M*(M+B)) % p:
           print("M % p = ", M, "%", p)
           R.append(M)
    for M in range(q):
        if C%q == (M*(M+B)) % q:
           print("M % q = ", M, "%", q)
           R.append(M)
输出:
1
M % p =  158558 % 868019
M % p =  529178 % 868019
M % q =  24100 % 913799
M % q =  755196 % 913799
2
M % p =  270422 % 875543
M % p =  432106 % 875543
M % q =  263205 % 904727
M % q =  497691 % 904727
3
M % p =  194177 % 597263
M % p =  553149 % 597263
M % q =  351135 % 890459
M % q =  385320 % 890459

5 中国剩余定理

从上面看,没个解都有两个情况,组合在一起是四个答案:

from sympy.ntheory.modular import crt
from Crypto.Util.number import long_to_bytes

M = [[(158558, 529178), (24100, 755196)], 
     [(270422, 432106), (263205, 497691)], 
     [(194177, 553149), (351135, 385320)]
    ]
V = [[868019, 913799], [875543, 904727], [597263, 890459]]

cnt = 0
for i in range(3):
    print(i)
    mp, mq = M[i]
    vx = V[i]
    #for mi,mj in zip(mp,mq):
    for mi in mp:
        for mj in mq:
            mx = [mi, mj]
            crt_m_v = crt(vx, mx) 
            print(crt_m_v)
            if crt_m_v:
                print(long_to_bytes(crt_m_v[0]))

输出

0
(mpz(435549524264), 793194894181)
b'eh\xc6Q('
(mpz(417932210640), 793194894181)
b'aN\xb3q\xd0'
(mpz(375261635239), 793194894181)
b'W_V"\xa7'
(mpz(357644321615), 793194894181)
b'SECCO'
1
(mpz(576969098734), 792127391761)
b'\x86V\t\xc5\xee'
(mpz(337076445535), 792127391761)
b'N{Ra_'
(mpz(455049897668), 792127391761)
b'i\xf3\x16f\xc4'
(mpz(215157244469), 792127391761)
b'2\x18_\x025'
2
(mpz(110102044649), 531838213717)
b'\x19\xa2\x97\xdf\xe9'
(mpz(368810693940), 531838213717)
b'U\xde\xd4\x954'
(mpz(163026475314), 531838213717)
b'%\xf5"\x992'
(mpz(421735124605), 531838213717)
b'b1_N}'

6 flag

SECCON{Ra_b1_N}