Presentation is loading. Please wait.

Presentation is loading. Please wait.

“WALK IN” SLIDE. August 14-15 2006 Hardening the Box: Xbox 360 and Windows Vista Security Michael Howard Software Security Guy Microsoft Corp.

Similar presentations


Presentation on theme: "“WALK IN” SLIDE. August 14-15 2006 Hardening the Box: Xbox 360 and Windows Vista Security Michael Howard Software Security Guy Microsoft Corp."— Presentation transcript:

1 “WALK IN” SLIDE

2 August 14-15 2006 Hardening the Box: Xbox 360 and Windows Vista Security Michael Howard Software Security Guy Microsoft Corp.

3 August 14-15 2006 Agenda

4

5 Securing software requires: Good design Writing more secure code in the first place Prohibiting banned functionality Static analysis tools Security testing Reducing attack surface A good base of defenses

6 August 14-15 2006 A Sample Scenario An imaginary game server Runs as SYSTEM Enumerates and hashes saved games to send to the user Saved game file name comes from a valid user over UDP In some code examples, error checking is removed for brevity

7 August 14-15 2006 Startup() EnumAndHashFiles() GetFileFromUser() HashOneFile() AddFileDataToList() SYSTEM 30,000 ft. View of the Code UDP “Gimme da saved game”

8 August 14-15 2006 ServiceMain() Startup() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() VOID WINAPI Startup(DWORD dwArgc,LPTSTR* lpszArgv) { // Initialization code // Setup threads // Create UDP listener while (true) { // Get directory from user over RPC wchar_t *wszDir = GetDirFromUser(); EnumAndHashFiles(wszDir); }

9 August 14-15 2006 ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() ServiceMain() VOID WINAPI Startup(DWORD dwArgc,LPTSTR* lpszArgv) { // Initialization code // Setup threads // Create UDP listener while (true) { // Get directory from user over RPC wchar_t *wszDir = GetDirFromUser(); EnumAndHashFiles(wszDir); } Run as network service

10 August 14-15 2006 ServiceMain() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() VOID WINAPI ServiceMain(DWORD dwArgc,LPTSTR* lpszArgv) { // Initialization code // Setup threads // Create UDP listener HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); LPCWSTR wszPrivs [] = { SE_TAKE_OWNERSHIP_NAME, SE_DEBUG_NAME, SE_CREATE_TOKEN_NAME, SE_ASSIGNPRIMARYTOKEN_NAME, SE_TCB_NAME, SE_SECURITY_NAME, SE_LOAD_DRIVER_NAME, SE_SYSTEMTIME_NAME, SE_BACKUP_NAME, SE_RESTORE_NAME, SE_SHUTDOWN_NAME, SE_AUDIT_NAME}; DropUnusedPrivs(wszPrivs,_countof(wszPrivs)); while (true) { // Get directory from user over RPC wchar_t *wszDir = GetDirFromUser(); EnumAndHashFiles(wszDir); } Terminate if a heap overflow occurs Drop unneeded privileges

11 August 14-15 2006 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy(wszPath2,(wchar_t*)wszPath); wcscat(wszPath2,L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; _snwprintf(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; }

12 August 14-15 2006 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy(wszPath2,(wchar_t*)wszPath); wcscat(wszPath2,L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; _snwprintf(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs

13 August 14-15 2006 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy_s(wszPath2,__countof(wszPath2),(wchar_t*)wszPath); wcscat_s(wszPath2,__countof(wszPath2),L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; swprintf_s(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs Replace Banned APIs

14 August 14-15 2006 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy_s(wszPath2,__countof(wszPath2),(wchar_t*)wszPath); wcscat_s(wszPath2,__countof(wszPath2),L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, GetCryptoProvider(), CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; swprintf_s(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs Replace Banned APIs “ Crypto Agility ” Get crypto provider from configuration

15 August 14-15 2006 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy_s(wszPath2,__countof(wszPath2),(wchar_t*)wszPath); wcscat_s(wszPath2,__countof(wszPath2),L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, GetCryptoProvider(), CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; swprintf_s(wszFilename, __countof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs Replace Banned APIs Static Analysis: Byte count vs. character count mismatch “ Crypto Agility ” Get crypto provider from configuration

16 August 14-15 2006 Not so fast… What’s SAL?

17 August 14-15 2006 Standard Annotation Language Used by static analysis tools such as /analyze Benefits of adding annotations to your code: Help the tools find harder to find bugs The process of adding annotations finds bugs! Bugs found are low noise

18 August 14-15 2006 SAL at Work void FillString( TCHAR* buf, size_t cchBuf, TCHAR ch) { for (size_t i = 0; i < cchBuf; i++) { buf[i] = ch; } These two arguments are related, but the compiler does not know!

19 August 14-15 2006 SAL at Work void FillString( __out_ecount(cchBuf) TCHAR* buf, size_t cchBuf, TCHAR ch) { for (size_t i = 0; i < cchBuf; i++) { buf[i] = ch; }

20 August 14-15 2006 SAL at Work __out_ecount(cchBuf) Out buffer, function will write to the buffer. Other examples include __in and __inout Element count. Other example includes bcount, byte count. __checkReturn __bcount_opt(_Size) malloc(__in size_t _Size); Optional, can be NULL Must check return value

21 August 14-15 2006 SAL at Work Warning C6386: Buffer overrun: accessing 'argument 1', the writable size is ‘200*2' bytes, but '420' bytes might be written: Lines: 33, 34 Warning C6387: 'argument 1' might be '0': this does not adhere to the specification for the function 'FillString': Lines: 33, 34 void FillString( __out_ecount(cchBuf) TCHAR* buf, size_t cchBuf, TCHAR ch) { for (size_t i = 0; i < cchBuf; i++) { buf[i] = ch; } void main() { TCHAR *buff = malloc(200 * sizeof(TCHAR)); FillString(buff,210,_T(’x’)); }

22 August 14-15 2006 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,CALG_SHA1,0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); free(pBuff); CryptDestroyHash(hHash); } CloseHandle(hFile); return true; }

23 August 14-15 2006 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(__in_z wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,CALG_SHA1,0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); free(pBuff); CryptDestroyHash(hHash); } CloseHandle(hFile); return true; } Add SAL annotation to detect bugs

24 August 14-15 2006 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(__in_z wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,GetHashAlg(),0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); free(pBuff); CryptDestroyHash(hHash); } CloseHandle(hFile); return true; } Add SAL annotation to detect bugs Replace Banned hash function “ Crypto-Agility ” Get hash alg from configuration

25 August 14-15 2006 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(__in_z wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,GetHashAlg(),0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); delete [] pBuff; CryptDestroyHash(hHash); } CloseHandle(hFile); return true; } Compiled code detects integer overflow automatically in ::new Static analysis spotted mismatch between new/delete [] (was free) “ Crypto-Agility ” Get hash alg from configuration Add SAL annotation to detect bugs Replace Banned hash function

26 August 14-15 2006 AddFileDataToList() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() void AddFileDataToList(wchar_t *wszName, BYTE *pHash, size_t cbHash) { // snip }

27 August 14-15 2006 AddFileDataToList() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() void AddFileDataToList(__in_z wchar_t *wszName, __in_bcount(cbHash) BYTE *pHash, size_t cbHash) { // snip } Add SAL annotation to detect bugs

28 August 14-15 2006 Required Compiler Settings Compile with /GS Detect some forms of stack-based buffer overrun at runtime If using EH then link with /SafeSEH Protect exception handlers Link with /NXCOMPAT Tested on a Data Execution Protection (DEP, or NX) compatible computer

29 August 14-15 2006 Fuzz Testing The service consumes: Files from the file system UDP data (file and directory name) from a user So we must fuzz both bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy(wszPath2,(wchar_t*)wszPath); wcscat(wszPath2,L"\\*.*"); wszPath is untrusted Buffer overflow when path is greater than 128 chars long

30 August 14-15 2006

31 D-Day is nearly here! User account control (UAC) enabled Your users will no longer be admins by default! Parental Controls requires child be a non- admin Allow parents to enforce limits on usage Know children’s activities Extensible by ISVs NOT A SECURITY FEATURE!

32 August 14-15 2006 UAC Do’s and Don’ts Don’t assume that the user installing game is the player Do perform game system-wide configuration during setup Do perform firewall operations during setup Be nice: let the user know! And that doesn’t mean turning off the firewall! Don’t perform admin tasks during 1 st run Per-user stuff must be done at 1 st run

33 August 14-15 2006 UAC Do’s and Don’ts Do write user data to user directories CSIDL_LOCAL_APPDATA, _PERSONAL, _COMMON_APPDATA If using Windows installer, use MSI patching (it does UAC hot-patching) Do sign your installer Don’t sign your installer with a self-issued certificate Do test as an installer and as a user

34 August 14-15 2006 “Invisible” Vista Defenses you get for free Firewall is on by default Data Execution Protection (DEP/NX) Supported by all AMD CPUs and most newer Intel CPUs (it’s more common than you think!) Some BIOSs disable by default :-( Service Hardening Network Access Policy for services mitigates rogue code running in the process from opening outbound ports

35 August 14-15 2006 “Random” Vista Defenses you get for free Address Space Layout Randomization Windows APIs commonly used by malware load at unpredictable addresses You can opt-in your code too (link with /DYNAMICBASE) Stack base is randomized per thread Heap is toughened Randomized base address Check-summed Terminate on heap corruption

36 August 14-15 2006 What You Should Do Start removing banned APIs Use static analysis tools, such as /analyze VSTS 2005 and Windows Development Kit Compile with SAL-annotated headers Add SAL to your own private headers Compile with /GS Link with /SafeSEH, /NXCompat and /DynamicBase Run and test on Windows Vista With DEP and UAC enabled Use PageHeap and AppVerifier

37 August 14-15 2006

38 Original Xbox Security Tales “It’s just a buffer overrun in a game…” Load game code of an original Xbox title did not correctly handle buffer overruns Bug used by hackers to overwrite the title signature public key in memory Via a crafted invalid save game One single title programming error led to Xbox 1 softmod Enabled offline cheating and game piracy (and not just against the title containing the programming error…) Need to do better in Xbox 360…

39 August 14-15 2006 Lessons Learned… Game Development Kit APIs automatically protect game data Maintaining Xbox 360 as a closed system All native code applications must be certified and signed by Microsoft No arbitrary network access from or to Xbox 360 Chances of malware, worm or virus intrusion low Hardware-protected multilayered security system Better protection against buffer overruns and other attacks against their persisted or in-memory code Resilient against application programming errors Extended Live security system

40 August 14-15 2006 Security You Get For Free Secure boot system Validated and certified executables Automatic network encryption/authentication Live security system counteracting cheating Automatic protection of HDD cache and MU content

41 August 14-15 2006 Protect Against Cheating Persisted game configuration data on DVD should be protected Multilevel security approach to protecting game data (in addition to DVD protection mechanisms) Put game configuration data in resource section of executable Protect config files with authenticated hash values Put hash values in Xex, and validate hashes before permitting the load to succeed

42 August 14-15 2006 More Anti-Cheating Measures Protect against DMA attacks Upcoming feature: protected data pages Allocated pages are protected by the Xbox 360 security system Protects security-relevant in-memory game state Utility Partition (hard-drive cache) is automatically integrity protected Use XContentCreate with confidence Get integrity validation for free Lock content to machine/profile when possible Game save Web sharing can lead to achievements/gamer score cheating

43 August 14-15 2006 Fuzz Testing Fuzz testing subjects program interfaces to random or semi-random data input Fuzz testing has been very successful for Xbox 360 team You can use it too! Fuzz test APIs that take input state not under title control Fuzz testing is one of the most successful ways to discover buffer overruns Buffer overruns on Xbox 360 could still lead to illicit data page manipulation Cheating still possible via buffer overruns

44 August 14-15 2006 Security Development Constraints No dynamic native code generation Creating native code on the fly is a high security risk Only cryptographically signed native code is allowed to execute on the console Protects against game code tampering Homebrewed code not entirely excluded: Hobbyists will be able to write managed code to run on Xbox 360 Stack memory is not executable Protection against buffer overrun attacks against the stack

45 August 14-15 2006 Summary

46 Questions?

47 Sample Manifest <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="Microsoft.DirectX SDK.EmptyProject" type="win32" /> DirectX SDK Sample Program. <requestedExecutionLevel level="asInvoker" uiAccess="false"/>...

48 August 14-15 2006 Resources Windows Vista SDK  http://windowssdk.msdn.microsoft.com/library/ http://windowssdk.msdn.microsoft.com/library/ User Account Control Guidelines  http://msdn.microsoft.com/windowsvista/default.aspx?pull=/librar y/en-us/dnlong/html/AccProtVista.asp http://msdn.microsoft.com/windowsvista/default.aspx?pull=/librar y/en-us/dnlong/html/AccProtVista.asp http://msdn.microsoft.com/windowsvista/default.aspx?pull=/librar y/en-us/dnlong/html/AccProtVista.asp Authenticode Signing for Game Developers  http://msdn.microsoft.com/library/default.asp?url=/ library/en- us/direct x9_c/Authenticode_Signing_for_Game_Developers.asp http://msdn.microsoft.com/library/default.asp?url=/ library/en- us/direct x9_c/Authenticode_Signing_for_Game_Developers.asp http://msdn.microsoft.com/library/default.asp?url=/ library/en- us/direct x9_c/Authenticode_Signing_for_Game_Developers.asp

49 August 14-15 2006 Resources Best Security Practices in Game Development  http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Best_Security_Practices_in_Game_Development.asp http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Best_Security_Practices_in_Game_Development.asp http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Best_Security_Practices_in_Game_Development.asp Gaming with Least-Privileged User Accounts  http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Gaming_with_Least_Privileged_User_Accounts.asp http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Gaming_with_Least_Privileged_User_Accounts.asp http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Gaming_with_Least_Privileged_User_Accounts.asp Patching Methods in Windows XP and Vista  http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Patching_Methods_in_Windows_XP_and_Vista.asp http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Patching_Methods_in_Windows_XP_and_Vista.asp http://msdn.microsoft.com/library/default.asp?url=/library/en- us/directx9_c/Patching_Methods_in_Windows_XP_and_Vista.asp

50 August 14-15 2006 Summary of Vista Defenses DefenseComments /GSReduces the chance that stack-based exploits work /SafeSEHReduce the chance that exception handler compromises work Heap Hardening and failfastReduce the chance that heap-based exploits work ASLRReduce the chance that “return to libc” exploits work Service HardeningReduces the chance that networking exploit code can open a socket Reduced Service PrivilegeReduces exploit code damage potential Data Execution ProtectionReduces the chance that exploit code will work in data segments Stack RandomizedReduces the predictability of stack addresses

51 © 2006 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary. DirectX Developer Center http://msdn.microsoft.com/directx Game Development MSDN Forums http://forums.microsoft.com/msdn Xbox 360 Central http://xds.xbox.com/ XNA Web site http://www.microsoft.com/xna http://msdn.microsoft.com/directx http://forums.microsoft.com/msdn http://xds.xbox.com/ http://www.microsoft.com/xna http://msdn.microsoft.com/directx http://forums.microsoft.com/msdn http://xds.xbox.com/ http://www.microsoft.com/xna End Slide


Download ppt "“WALK IN” SLIDE. August 14-15 2006 Hardening the Box: Xbox 360 and Windows Vista Security Michael Howard Software Security Guy Microsoft Corp."

Similar presentations


Ads by Google