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得:
爆破: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}'