; GCHQ canyoucrackit.co.uk stage 1 solution ; Dr Gareth Owen, School of Engineering, University of Greenwich, England ; g.h.owen@gre.ac.uk ; Explanation: http://gchqchallenge.blogspot.com ; To run: ; nasm -f elf p1-complete.asm ; gcc -o p1 p1-complete.asm ; ./p1 global main main: jmp start ; unused - code for part 3 scasd ret 0xa3bf ; unused - end code for part 3 start: sub esp,0x100 ; 4096 bytes xor ecx,ecx ; loop through 256 bytes of memory and set values to equal offset (e.g. pos 1 = val 1) ; RC4 KSA initialisation ksa_part1_loop: mov [esp+ecx],cl inc cl jnz ksa_part1_loop xor eax,eax ; key for RC4 algorithm mov edx,0xdeadbeef ksa_key_loop: ; cl used as j (loop counter) add al,[esp+ecx]; add al,dl ; take cur byte from key ror edx,0x8 ; next byte in key (rotate 8 bits) mov bl,[esp+ecx] mov bh,[esp+eax] mov [esp+eax],bl mov [esp+ecx],bh inc cl jnz ksa_key_loop jmp label1 decrypt: mov ebx,esp add ebx,0x4 ; keystream location pop esp ; loads end of program address into ESP (using location from earlier call which placed it on stack ) ; sanity check pop eax ; ensure we're at end of program (see last four instructions) cmp eax,0x41414141 jnz myexit ; esp = beginning of data from image ; check valid data pop eax cmp eax,0x42424242 jnz myexit ; begin decryption pop edx ; get num bytes ( = 50/32h) mov ecx,edx mov esi,esp ; stack pointer into esi mov edi,ebx ; destination is old esp + 4 sub edi,ecx ; move back down stack 32 bytes rep movsb ; move ECX bytes from ESI to EDI mov esi,ebx mov ecx,edx mov edi,ebx sub edi,ecx xor eax,eax xor ebx,ebx xor edx,edx decrypt_loop: ; main decrypt loop inc al add bl,[esi+eax] mov dl,[esi+eax] mov dh,[esi+ebx] mov [esi+eax],dh mov [esi+ebx],dl add dl,dh xor dh,dh mov bl,[esi+edx] mov dl,[edi] xor dl,bl ; xor with keystraem mov [edi],dl ; store result inc edi dec ecx jnz decrypt_loop myexit: mov eax, 4 ; sys_write mov ebx, 1 ; stdout mov edx, 0x32 ; length lea ecx, [edi-0x32] ; location int 0x80 xor ebx,ebx ; clear ebx mov eax,ebx ; clear eax inc al ; set eax to 1 (syscall for exit) int 0x80 ; make syscall label1: nop nop call decrypt ; CALL SO THAT WE GET THIS LOCATION ONTO THE STACK (e.g. end of file for later for decryption) ; 0x41414141 (to check we're in right place later) dd 0x41414141 ;inc ecx ;inc ecx ;inc ecx ;inc ecx ; INSERT STUFF TO BE DECRYPTED HERE db 042h db 042h db 042h db 042h db 032h db 00h db 00h db 00h db 091h db 0d8h db 0f1h db 06dh db 070h db 020h db 03ah db 0abh db 067h db 09ah db 0bh db 0c4h db 091h db 0fbh db 0c7h db 066h db 0fh db 0fch db 0cdh db 0cch db 0b4h db 02h db 0fah db 0d7h db 077h db 0b4h db 054h db 038h db 0abh db 01fh db 0eh db 0e3h db 08eh db 0d3h db 0dh db 0ebh db 099h db 0c3h db 093h db 0feh db 0d1h db 02bh db 01bh db 011h db 0c6h db 011h db 0efh db 0c8h db 0cah db 02fh