Recently Updated
Dec 14: Happy Cryptmas
Challenge
todays gift was encrypted with the attached program. try to unbox your xmas present.
1
Flag: 7A9FDCA5BB061D0D638BE1442586F3488B536399BA05A14FCAE3F0A2E5F268F2F3142D1956769497AE677A12E4D44EC727E255B391005B9ADCF53B4A74FFC34C
Solution
This is a Mach-O executable which we disassemble the file with Hopper:
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
================ B E G I N N I N G O F P R O C E D U R E ================
;
; Section __text
;
; Range 0x100000cc0 - 0x100000e66 (422 bytes)
; File offset 3264 (422 bytes)
; Flags : 0x80000400
;
0000000100000cc1 mov rbp, rsp
0000000100000cc4 sub rsp, 0xc0
0000000100000ccb mov rax, qword [ds:imp___got____stack_chk_guard] ; imp___got____stack_chk_guard
0000000100000cd2 mov rax, qword [ds:rax]
0000000100000cd5 mov qword [ss:rbp+var_8], rax
0000000100000cd9 mov dword [ss:rbp+var_64], 0x0
0000000100000ce0 mov dword [ss:rbp+var_68], edi
0000000100000ce3 mov qword [ss:rbp+var_70], rsi
0000000100000ce7 cmp dword [ss:rbp+var_68], 0x1
0000000100000ceb jne 0x100000cfd
0000000100000cf1 mov dword [ss:rbp+var_64], 0x0
0000000100000cf8 jmp 0x100000e32
0000000100000cfd lea rdi, qword [ss:rbp+var_50] ; XREF=_main+43
0000000100000d01 call imp___stubs____gmpz_init
0000000100000d06 lea rdi, qword [ss:rbp+var_60]
0000000100000d0a call imp___stubs____gmpz_init
0000000100000d0f lea rsi, qword [ds:0x100000f18] ; "F66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51"
0000000100000d16 mov edx, 0x10
0000000100000d1b lea rdi, qword [ss:rbp+var_20]
0000000100000d1f call imp___stubs____gmpz_init_set_str
0000000100000d24 lea rsi, qword [ds:0x100000f99] ; "65537"
0000000100000d2b mov edx, 0xa
0000000100000d30 lea rdi, qword [ss:rbp+var_40]
0000000100000d34 mov dword [ss:rbp+var_74], eax
0000000100000d37 call imp___stubs____gmpz_init_set_str
0000000100000d3c mov edx, 0x1
0000000100000d41 mov ecx, 0x1
0000000100000d46 xor r8d, r8d
0000000100000d49 xor r9d, r9d
0000000100000d4c lea rdi, qword [ss:rbp+var_50]
0000000100000d50 mov rsi, qword [ss:rbp+var_70]
0000000100000d54 mov rsi, qword [ds:rsi+0x8]
0000000100000d58 mov qword [ss:rbp+var_80], rdi
0000000100000d5c mov rdi, rsi ; argument "s" for method imp___stubs__strlen
0000000100000d5f mov dword [ss:rbp+var_84], eax
0000000100000d65 mov dword [ss:rbp+var_88], edx
0000000100000d6b mov qword [ss:rbp+var_90], rcx
0000000100000d72 mov dword [ss:rbp+var_94], r8d
0000000100000d79 mov qword [ss:rbp+var_A0], r9
0000000100000d80 call imp___stubs__strlen
0000000100000d85 mov rcx, qword [ss:rbp+var_70]
0000000100000d89 mov rcx, qword [ds:rcx+0x8]
0000000100000d8d mov rdi, qword [ss:rbp+var_80]
0000000100000d91 mov rsi, rax
0000000100000d94 mov edx, dword [ss:rbp+var_88]
0000000100000d9a mov rax, qword [ss:rbp+var_90]
0000000100000da1 mov qword [ss:rbp+var_A8], rcx
0000000100000da8 mov rcx, rax
0000000100000dab mov r8d, dword [ss:rbp+var_94]
0000000100000db2 mov r9, qword [ss:rbp+var_A0]
0000000100000db9 mov r10, qword [ss:rbp+var_A8]
0000000100000dc0 mov qword [ss:rsp], r10
0000000100000dc4 call imp___stubs____gmpz_import
0000000100000dc9 lea rsi, qword [ss:rbp+var_20]
0000000100000dcd lea rdi, qword [ss:rbp+var_50]
0000000100000dd1 call imp___stubs____gmpz_cmp
0000000100000dd6 cmp eax, 0x0
0000000100000dd9 jle 0x100000de4
0000000100000ddf call imp___stubs__abort
0000000100000de4 lea rcx, qword [ss:rbp+var_20] ; XREF=_main+281
0000000100000de8 lea rdx, qword [ss:rbp+var_40]
0000000100000dec lea rsi, qword [ss:rbp+var_50]
0000000100000df0 lea rdi, qword [ss:rbp+var_60]
0000000100000df4 call imp___stubs____gmpz_powm
0000000100000df9 lea rdi, qword [ds:0x100000f9f] ; "Crypted: %ZX\\n"
0000000100000e00 lea rsi, qword [ss:rbp+var_60]
0000000100000e04 mov al, 0x0
0000000100000e06 call imp___stubs____gmp_printf
0000000100000e0b xor r8d, r8d
0000000100000e0e lea rcx, qword [ss:rbp+var_40]
0000000100000e12 lea rdx, qword [ss:rbp+var_20]
0000000100000e16 lea rsi, qword [ss:rbp+var_60]
0000000100000e1a lea rdi, qword [ss:rbp+var_50]
0000000100000e1e mov dword [ss:rbp+var_AC], eax
0000000100000e24 mov al, 0x0
0000000100000e26 call imp___stubs____gmpz_clears
0000000100000e2b mov dword [ss:rbp+var_64], 0x0
0000000100000e32 mov eax, dword [ss:rbp+var_64] ; XREF=_main+56
0000000100000e35 mov rcx, qword [ds:imp___got____stack_chk_guard] ; imp___got____stack_chk_guard
0000000100000e3c mov rcx, qword [ds:rcx]
0000000100000e3f mov rdx, qword [ss:rbp+var_8]
0000000100000e43 cmp rcx, rdx
0000000100000e46 mov dword [ss:rbp+var_B0], eax
0000000100000e4c jne 0x100000e61
0000000100000e52 mov eax, dword [ss:rbp+var_B0]
0000000100000e58 add rsp, 0xc0
0000000100000e5f pop rbp
0000000100000e60 ret
0000000100000e61 call imp___stubs____stack_chk_fail ; XREF=_main+396
; endp
pseudocode generated by Hopper disassembler:
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
function _main {
var_8 = **__stack_chk_guard;
var_64 = 0x0;
var_68 = LODWORD(arg0);
var_70 = arg1;
if (var_68 != 0x1) goto loc_100000cfd;
goto loc_100000cf1;
loc_100000cfd:
__gmpz_init();
__gmpz_init();
rax = __gmpz_init_set_str();
var_74 = LODWORD(rax);
rax = __gmpz_init_set_str();
rsi = *(var_70 + 0x8);
var_80 = var_50;
var_84 = LODWORD(rax);
var_88 = LODWORD(0x1);
var_90 = 0x1;
var_94 = LODWORD(0x0);
var_A0 = 0x0;
rax = strlen(rsi);
rcx = *(var_70 + 0x8);
var_A8 = rcx;
__gmpz_import();
if (LODWORD(__gmpz_cmp()) <= 0x0) goto loc_100000de4;
goto loc_100000ddf;
loc_100000de4:
__gmpz_powm();
rax = __gmp_printf();
var_AC = LODWORD(rax);
__gmpz_clears();
var_64 = 0x0;
loc_100000e32:
rcx = *__stack_chk_guard;
rcx = *rcx;
var_B0 = LODWORD(var_64);
if (rcx == var_8) {
LODWORD(rax) = var_B0;
return rax;
}
else {
rax = __stack_chk_fail();
}
return rax;
loc_100000ddf:
rax = abort();
loc_100000cf1:
var_64 = 0x0;
goto loc_100000e32;
}
or, more clearly:
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
int _main(int arg0, int arg1) {
var_8 = **___stack_chk_guard;
var_70 = arg1;
if (arg0 != 0x1) goto loc_100000cfd;
loc_100000e32:
var_B0 = 0x0;
if (**___stack_chk_guard == var_8) {
rax = var_B0;
}
else {
rax = __stack_chk_fail();
}
return rax;
loc_100000cfd:
__gmpz_init(&var_50);
__gmpz_init(&var_60);
__gmpz_init_set_str(&var_20, "F66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51", 0x10);
__gmpz_init_set_str(&var_40, "65537", 0xa);
__gmpz_import(&var_50, strlen(*(var_70 + 0x8)), 0x1, 0x1, 0x0, 0x0, *(var_70 + 0x8));
if (__gmpz_cmp(&var_50, &var_20) <= 0x0) goto loc_100000de4;
loc_100000ddf:
rax = abort();
return rax;
loc_100000de4:
__gmpz_powm(&var_60, &var_50, &var_40, &var_20);
__gmp_printf("Crypted: %ZX\n", &var_60);
__gmpz_clears(&var_50, &var_60, &var_20, &var_40, 0x0);
goto loc_100000e32;
}
This looks like RSA, with the commonly used value for exponent e=65537
and N=0xF66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51
We get the prime factors of N
(p
and q
) using factordb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3
from Crypto.PublicKey import RSA
import gmpy2
def int2Text(number, size):
text = "".join([chr((number >> j) & 0xff) for j in reversed(range(0, size << 3, 8))])
return text.lstrip("\x00")
N = 0xF66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51
C = 0x7A9FDCA5BB061D0D638BE1442586F3488B536399BA05A14FCAE3F0A2E5F268F2F3142D1956769497AE677A12E4D44EC727E255B391005B9ADCF53B4A74FFC34C
p = 18132985757038135691
q = 711781150511215724435363874088486910075853913118425049972912826148221297483065007967192431613422409694054064755658564243721555532535827
e = 65537
r = (p-1)*(q-1)
d = int(gmpy2.divm(1, e, r))
rsa = RSA.construct((N,e,d,p,q))
pt = rsa.decrypt(C)
print(int2Text(pt,1000))
this prints our flag.
Flag
HV17-5BMu-mgD0-G7Su-EYsp-Mg0b