Friday, 29 October 2010 2k10 CTF "Pirates crackme" write-up CTF 2k10 ~ Zenk-Security

Final scoreboard:

Congratz guys !

Write up of the first challenge we have break: Pirates crackme.

15 - Pirates Crackme

Captian Jack asks you to keygen this application.
He rewards you with 200 coins, if your give him the serial for: Captian Jack

gold: 200 +3 (1st), +2 (2nd), +1 (3rd)

Analyze with PEiD: N/A
Plugin KANAL -> Big number
Time to load it in olly:
I follow:
00401137 |. E8 E4FEFFFF CALL 00401020 ; piratecr.00401020

And we follow again:
004010AF |. E8 7C030000 CALL 00401430 ; piratecr.00401430

00401430 /$ 55 PUSH EBP

Olly listing:
004014A4 |. C74424 04 24E>MOV DWORD PTR SS:[ESP+4],41E024 ; ASCII "10001"
004014AC |. 8D8424 A00000>LEA EAX,DWORD PTR SS:[ESP+A0]
004014B3 |. 890424 MOV DWORD PTR SS:[ESP],EAX
004014B6 |. E8 05100000 CALL 004024C0 ; piratecr.004024C0
004014BB |. C74424 08 100>MOV DWORD PTR SS:[ESP+8],10
004014C3 |. C74424 04 2CE>MOV DWORD PTR SS:[ESP+4],41E02C ; ASCII "7D324938E2EF6D9548FAB62E6919BBB1"
RSA, Thanks KANAL :)

Final cmp:
004015AC |. 85C0 TEST EAX,EAX
004015AE |. 74 1C JE SHORT 004015CC ; piratecr.004015CC
004015B0 |. C70424 80E041>MOV DWORD PTR SS:[ESP],41E080 ; ASCII "invalid!"
004015B7 |. E8 A4120000 CALL 00402860 ; piratecr.00402860
004015BC |. 31C0 XOR EAX,EAX
004015BE |. 81C4 C4000000 ADD ESP,0C4
004015C4 |. 5B POP EBX
004015C5 |. 5E POP ESI
004015C6 |. 5F POP EDI
004015C7 |. C9 LEAVE
004015C8 |. C3 RETN
004015C9 | 8D76 00 LEA ESI,DWORD PTR DS:[ESI]
004015CC |> C70424 6DE041>MOV DWORD PTR SS:[ESP],41E06D ; ASCII "Congratz! valid !"
004015D3 |. E8 88120000 CALL 00402860 ; piratecr.00402860

serial must have more than 18 chars
0040154D |. 83F8 12 CMP EAX,12
00401550 |. 8B5424 1C MOV EDX,DWORD PTR SS:[ESP+1C]
00401554 |. 0F8E 8E000000 JLE piratecr.004015E8
004015E8 |> 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; |
004015EC |. C70424 5FE0410>MOV DWORD PTR SS:[ESP],piratecr.0041E05F ; |ASCII "wrong size%d
004015F3 |. E8 18B40100 CALL ; \printf

C= M ^ e mod n (Crypt)
M= C ^ d mod n (Uncrypt)

C= Cipher text
M= Message
e= public exponent
d= private exponent
n = result of p and q

what's we have ?
10001 = e
7D324938E2EF6D9548FAB62E6919BBB1 = n

That enought.
For solve a crackme we need to know 'n' and 'e'
Because those data are not public and used for crypt the text you have entered in the binnary.
But here... we dont want crypt !
so we need 'd'
With 'n' and 'e' we found 'p' and 'q' by factorising 'n' and then.. calculate 'd'
you can do this with RSA-Tool 2 by tE!
So we have 4F90128A8D65DD7C7919EDEFCCD4EEB5... :)

The algorithm is working like this:
xor byte ptr (Captian Jack),0xF00Dh
hash(Captian Jack == F04E)
*serial=hash^4F90128A8D65DD7C7919EDEFCCD4EEB5 mod 7D324938E2EF6D9548FAB62E6919BBB1 == 36D13BA5C430D47B27F7E6DE2198C6A6

User: Captian Jack
Serial: 36D13BA5C430D47B27F7E6DE2198C6A6

You solved this challenge as first!
Gold: 203

And finaly...

Want the source code ? sure.
I've used 2 lib who are not with the masm32 sdk10...:
biglib v. 0.01e by roy|fleur, and the mfmplayer library.
You can download the package here (The pirate crackme is also inside)

.model  flat, stdcall
option  casemap :none
includelib  mfmplayer.lib

; RC

nMusicSize     DWORD      ?
pMusic         LPVOID     ?

    invoke  GetModuleHandle, NULL
    mov hInstance, eax
    invoke  DialogBoxParam, hInstance, IDD_MAIN, 0, offset DlgProc, 0
    invoke  ExitProcess, eax
    invoke  InitCommonControls

DlgProc proc uses esi edi hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    mov eax,uMsg
    .if eax == WM_INITDIALOG
        invoke  LoadIcon,hInstance,200
    invoke FindResource, hInstance, IDM_TAPZ, RT_RCDATA
    push eax
    invoke SizeofResource, hInstance, eax
    mov nMusicSize, eax
    pop eax
    invoke LoadResource, hInstance, eax
    invoke LockResource, eax
    mov esi, eax
    mov eax, nMusicSize
    add eax, SIZEOF nMusicSize
    invoke GlobalAlloc, GPTR, eax
    mov pMusic, eax
    mov ecx, nMusicSize
    mov dword ptr [eax], ecx
    add eax, SIZEOF nMusicSize
    mov edi, eax
    rep movsb
    pop esi
    invoke mfmPlay, pMusic
        invoke  LoadIcon,hInstance,200
        invoke  SendMessage, hWnd, WM_SETICON, 1, eax
        invoke  GetDlgItem,hWnd,IDC_NAME
        invoke  SendMessage,eax,EM_LIMITTEXT,31,0
        invoke  GetDlgItem,hWnd,IDC_SERIAL
        invoke  SendMessage,eax,EM_LIMITTEXT,32,0
        invoke  _BigIn,addr N,16,addr N_Big
        invoke  _BigIn,addr D,16,addr D_Big
    .elseif eax == WM_COMMAND
        mov eax,wParam
        .if eax == IDB_EXIT
            invoke  SendMessage, hWnd, WM_CLOSE, 0, 0
        .elseif ax == IDC_NAME
            shr eax, 16
            .if ax == EN_CHANGE
                jmp @f
        .elseif eax == IDB_GENERATE
            @@:invoke   GetDlgItemText,hWnd,IDC_NAME,addr szName,100h
            .if eax == 0
                invoke  SetDlgItemText,hWnd,IDC_SERIAL,chr$('Enter your name, buddy!')
            mov Dw1,0F00Dh
            mov esi,offset szName
            mov ecx,eax
            xor eax,eax
            xor Dw1,eax
            loop @B
            mov eax,Dw1
            rol ax,8
            mov Dw1,eax
            invoke  HexToChar,addr Dw1,addr Hash,2
            invoke  _BigIn,addr Hash,16,addr M_Big
            invoke  _BigPowMod,addr M_Big,addr D_Big,addr N_Big,addr C_Big
            invoke  _BigOut,addr C_Big,16,addr Serial
            invoke  SetDlgItemText,hWnd,IDC_SERIAL,addr Serial
            invoke  RtlZeroMemory,addr szName,sizeof szName
            invoke  RtlZeroMemory,addr Hash,sizeof Hash
            invoke  RtlZeroMemory,addr M_Big,sizeof M_Big
            invoke  RtlZeroMemory,addr C_Big,sizeof C_Big
            invoke  RtlZeroMemory,addr Serial,sizeof Serial
    .elseif eax == WM_CLOSE
    invoke mfmPlay, 0
    invoke GlobalFree, pMusic
        invoke  EndDialog, hWnd, 0
    xor eax,eax
DlgProc endp
end start
include     \masm32\macros\macros.asm
includelib  user32.lib
includelib  kernel32.lib
includelib  comctl32.lib
includelib  biglib.lib


HexToChar proc HexValue:DWORD,CharValue:DWORD,HexLength:DWORD
mov esi,[ebp+8]
mov edi,[ebp+0Ch]
mov ecx,[ebp+10h]
mov ah, al
and ah, 0fh
shr al, 4
add al, '0'
add ah, '0'
.if al > '9'
add al, 'A'-'9'-1
.if ah > '9'
add ah, 'A'-'9'-1
loopd @HexToChar
HexToChar endp

IDD_MAIN        equ 1000
IDB_EXIT        equ 1001
IDC_NAME        equ 1002
IDC_SERIAL      equ 1005
IDB_GENERATE    equ 1006
IDB_ABOUT       equ 1007

Dw1         dd  0,0
N           db  "7D324938E2EF6D9548FAB62E6919BBB1",0
D           db  "4F90128A8D65DD7C7919EDEFCCD4EEB5",0

hInstance   dd  ?
szName      db  100h    dup(?)
Hash        db  100h    dup(?)
N_Big       db  100h    dup(?)
D_Big       db  100h    dup(?)
M_Big       db  100h    dup(?)
C_Big       db  100h    dup(?)
Serial      db  100h    dup(?)

;This Resource Script was generated by WinAsm Studio.

#define IDD_MAIN 1000
#define IDB_EXIT 1001
#define IDC_STATIC1003 1003
#define IDC_STATIC1004 1004
#define IDC_NAME 1002
#define IDC_SERIAL 1005
#define IDB_GENERATE 1006
#define IDI_ICON 100
#define IDM_TAPZ 444
#define IDC_IMAGE1008 1008
#define IDC_STATIC1009 1009

1 24 DISCARDABLE "manifest.xml"
IDD_MAIN DIALOGEX 10,10,264,143

CAPTION " CTF 2010 - Pirates Crackme *KeyGen*"
FONT 8,"Tahoma"
STYLE 0x90c80804
EXSTYLE 0x00000188

    CONTROL "Exit",IDB_EXIT,"Button",0x10010000,217,126,45,13,0x00000000
    CONTROL "Zenk-Security",IDC_NAME,"Edit",0x50010000,27,89,234,13,0x00000200
    CONTROL "Name",IDC_STATIC1003,"Static",0x50000000,3,89,20,8,0x00000000
    CONTROL "Serial",IDC_STATIC1004,"Static",0x50000000,4,108,20,9,0x00000000
    CONTROL "",IDC_SERIAL,"Edit",0x50010000,27,108,234,12,0x00000200
    CONTROL "GEN",IDB_GENERATE,"Button",0x10010000,167,126,44,13,0x00000000
    CONTROL "#946",IDC_IMAGE1008,"Static",0x5080020e,3,3,257,81,0x00000000
    CONTROL "27/10/2010",IDC_STATIC1009,"Static",0x58000000,3,132,81,7,0x00000000


  1. Oh god, RSA !
    That must be fun :D

  2. Xylitol from Easy keygen you :) Bignums were implemented with GNU PG. Could be useful to have IDA sigs for future. Congrats on being first (+3)!