After examining some code retrieved by our operative we are unsure whether it was written by an evil genius or a google employee. We will let you decide.

Summary: linux x64 binary, obfuscated xor

The main code is rather simple:

.text : 0000004006D0 main proc near .text : 0000004006D0 mov [ rsp + var_18 ] , rbx .text : 0000004006D5 mov [ rsp + var_10 ] , rbp .text : 0000004006DA mov rbx , rsi .text : 0000004006DD mov [ rsp + var_8 ] , r12 .text : 0000004006E2 sub rsp , 38h .text : 0000004006E6 cmp edi , 1 .text : 0000004006E9 jle short loc_40075A .text : 0000004006EB mov r12 , [ rsi + 8 ] .text : 0000004006EF mov rdi , r12 .text : 0000004006F2 call _strlen ; strlen(argv[1]) .text : 0000004006F7 cmp rax , 1Fh ; 31 .text : 0000004006FB jnz short loc_40075A .text : 0000004006FD mov rcx , rsp .text : 000000400700 mov rsi , r12 .text : 000000400703 mov edi , 8 .text : 000000400708 mov edx , offset mess .text : 00000040070D call frob ; encrypt .text : 000000400712 mov rdi , cs : expected .text : 000000400719 mov ecx , 20h .text : 00000040071E mov rsi , rsp .text : 000000400721 repe cmpsb ; compare result with hardcoded data .text : 000000400723 jz short loc_400748 .text : 000000400725 mov edi , offset s ; "Invalid passcode" .text : 00000040072A call _puts .text : 00000040072F loc_40072F : ; CODE XREF: main+88j .text : 00000040072F xor eax , eax .text : 000000400731 mov rbx , [ rsp + 38h + var_18 ] .text : 000000400736 mov rbp , [ rsp + 38h + var_10 ] .text : 00000040073B mov r12 , [ rsp + 38h + var_8 ] .text : 000000400740 add rsp , 38h .text : 000000400744 retn .text:0000004006D0 main proc near .text:0000004006D0 mov [rsp+var_18], rbx .text:0000004006D5 mov [rsp+var_10], rbp .text:0000004006DA mov rbx, rsi .text:0000004006DD mov [rsp+var_8], r12 .text:0000004006E2 sub rsp, 38h .text:0000004006E6 cmp edi, 1 .text:0000004006E9 jle short loc_40075A .text:0000004006EB mov r12, [rsi+8] .text:0000004006EF mov rdi, r12 .text:0000004006F2 call _strlen ; strlen(argv[1]) .text:0000004006F7 cmp rax, 1Fh ; 31 .text:0000004006FB jnz short loc_40075A .text:0000004006FD mov rcx, rsp .text:000000400700 mov rsi, r12 .text:000000400703 mov edi, 8 .text:000000400708 mov edx, offset mess .text:00000040070D call frob ; encrypt .text:000000400712 mov rdi, cs:expected .text:000000400719 mov ecx, 20h .text:00000040071E mov rsi, rsp .text:000000400721 repe cmpsb ; compare result with hardcoded data .text:000000400723 jz short loc_400748 .text:000000400725 mov edi, offset s ; "Invalid passcode" .text:00000040072A call _puts .text:00000040072F loc_40072F: ; CODE XREF: main+88j .text:00000040072F xor eax, eax .text:000000400731 mov rbx, [rsp+38h+var_18] .text:000000400736 mov rbp, [rsp+38h+var_10] .text:00000040073B mov r12, [rsp+38h+var_8] .text:000000400740 add rsp, 38h .text:000000400744 retn

Basically just some encryption and result compare. The interesting part is frob function. It has a bunch of SSE instructions, processing the encryption.

I decided to see what the result is and I patched the binary to output the result of the encryption:

.text : 000000000040070D call frob .text : 0000000000400712 mov rdi , cs : expected .text : 0000000000400719 mov ecx , 20h ; addr .text : 000000000040071E xor rax , rax .text : 0000000000400721 mov al , 1 .text : 0000000000400723 xor rdi , rdi .text : 0000000000400726 inc rdi .text : 0000000000400729 mov rsi , rsp ; encrypted data .text : 000000000040072C mov rdx , rcx ; len = 32 .text : 000000000040072F syscall ; write syscall .text : 0000000000400731 retn .text:000000000040070D call frob .text:0000000000400712 mov rdi, cs:expected .text:0000000000400719 mov ecx, 20h ; addr .text:000000000040071E xor rax, rax .text:0000000000400721 mov al, 1 .text:0000000000400723 xor rdi, rdi .text:0000000000400726 inc rdi .text:0000000000400729 mov rsi, rsp ; encrypted data .text:000000000040072C mov rdx, rcx ; len = 32 .text:000000000040072F syscall ; write syscall .text:0000000000400731 retn

Let’s see:

$ . / psimd " `perl -e 'print "A"x1 . "B"x30;'` " | xxd 0000000: 77de 77f3 823e 3815 01c2 2a91 441c 2926 w.w.. > 8 ... * .D. ) & 0000010: 8ca8 c669 42c6 8cda 8e25 03e7 ebf6 b23b ...iB.... % .....; $ . / psimd " `perl -e 'print "A"x2 . "B"x29;'` " | xxd 0000000: 77dd 77f3 823e 3815 01c2 2a91 441c 2926 w.w.. > 8 ... * .D. ) & 0000010: 8ca8 c669 42c6 8cda 8e25 03e7 ebf6 b23b ...iB.... % .....; $ . / psimd " `perl -e 'print "A"x3 . "B"x28;'` " | xxd 0000000: 77dd 74f3 823e 3815 01c2 2a91 441c 2926 w.t.. > 8 ... * .D. ) & 0000010: 8ca8 c669 42c6 8cda 8e25 03e7 ebf6 b23b ...iB.... % .....; $ ./psimd "`perl -e 'print "A"x1 . "B"x30;'`" | xxd 0000000: 77de 77f3 823e 3815 01c2 2a91 441c 2926 w.w..>8...*.D.)& 0000010: 8ca8 c669 42c6 8cda 8e25 03e7 ebf6 b23b ...iB....%.....; $ ./psimd "`perl -e 'print "A"x2 . "B"x29;'`" | xxd 0000000: 77dd 77f3 823e 3815 01c2 2a91 441c 2926 w.w..>8...*.D.)& 0000010: 8ca8 c669 42c6 8cda 8e25 03e7 ebf6 b23b ...iB....%.....; $ ./psimd "`perl -e 'print "A"x3 . "B"x28;'`" | xxd 0000000: 77dd 74f3 823e 3815 01c2 2a91 441c 2926 w.t..>8...*.D.)& 0000010: 8ca8 c669 42c6 8cda 8e25 03e7 ebf6 b23b ...iB....%.....;

Hmm it’s very likely to be just XOR. Let’s check:

# get hardcoded data from binary $ dd bs = 1 if =simd of =data skip =$ ( rax2 0x2458 ) count = 32 32 + 0 records in 32 + 0 records out 32 bytes ( 32 B ) copied, 0.000348474 s, 91.8 kB / s $ . / psimd " `perl -e 'print "A"x31;'` " > ENCA $ xor -f ENCA -s $ ( perl -e 'print "A"x32' ) > key $ xor -f key -f data 4rnt_v3ct0r_1nstruct10ns_c00l? ! A # get hardcoded data from binary $ dd bs=1 if=simd of=data skip=$(rax2 0x2458) count=32 32+0 records in 32+0 records out 32 bytes (32 B) copied, 0.000348474 s, 91.8 kB/s $ ./psimd "`perl -e 'print "A"x31;'`" >ENCA $ xor -f ENCA -s $(perl -e 'print "A"x32') >key $ xor -f key -f data 4rnt_v3ct0r_1nstruct10ns_c00l?!A

Indeed! The flag: 4rnt_v3ct0r_1nstruct10ns_c00l?!