Banned APIs and Sin Within!

Report
Banned APIs and Sin Within!
Michael Howard
[email protected]
Who Is This Guy?
•
•
•
•
•
[email protected]
Christian (imperfect in every possible way!)
Microsoft employee for 20 years
Always in security
Worked on the Microsoft SDL since inception
Goals and Non-Goals
• I am not one for drawing analogies
– “Security Analogies are usually Wrong”
http://blogs.msdn.com/b/michael_howard/archiv
e/2006/03/09/547575.aspx
• I use quotes from the Bible to
compare/contrast software security
• “The Bible is correct, your code is not.” :-)
If cars operated in an environment like
the Internet, they would…
• Be driven by people with little regard for safe automobile
operation.
• Have their windshields shot out every 60 secs.
• Once you have bullet-proof glass, the bad guys place nails at
freeway off-ramps next to signs like, “free coffee this way”
– and someone is always trying to steal your keys
– and pull out your sparkplugs
– and siphon your gas
• Talking of gas, you fill up at a Shell station, only to realize the gas
really isn’t gas, it’s vegetable oil and sand
• Oh, that gas station isn’t a Shell station, it certainly looked like one,
but they took your credit card details anyway
• As this all goes on, you can’t see the adversary
• And the adversaries are sharing new weapons with each other
The SDL
• A set of process changes that help improve
software security
• Over 100 requirements and recommendations
• About 30 deal with memory corruption
• Removing banned APIs is one such
requirement
What Are The Banned APIs?
• Mostly memory corruption APIs
– strcpy …
– strcat …
– strncpy …
– strncat …
– sprintf …
– gets …
Banned APIs
strcpy, strcpyA, strcpyW, wcscpy, _tcscpy,
_mbscpy, StrCpy, StrCpyA, StrCpyW, lstrcpy,
lstrcpyA, lstrcpyW, _tccpy, _mbccpy
strcat, strcatA, strcatW, wcscat, _tcscat,
_mbscat, StrCat, StrCatA, StrCatW, lstrcat,
lstrcatA, lstrcatW, StrCatBuff, StrCatBuffA,
StrCatBuffW, StrCatChainW, _tccat,
_mbccat
strncpy, wcsncpy, _tcsncpy, _mbsncpy,
_mbsnbcpy, StrCpyN, StrCpyNA, StrCpyNW,
StrNCpy, strcpynA, StrNCpyA, StrNCpyW,
lstrcpyn, lstrcpynA, lstrcpynW
strncat, wcsncat, _tcsncat, _mbsncat,
_mbsnbcat, StrCatN, StrCatNA, StrCatNW,
StrNCat, StrNCatA, StrNCatW, lstrncat,
lstrcatnA, lstrcatnW, lstrcatn
CharToOem, CharToOemA, CharToOemW,
OemToChar, OemToCharA, OemToCharW,
CharToOemBuffA, CharToOemBuffW
wnsprintf, wnsprintfA, wnsprintfW,
sprintfW, sprintfA, wsprintf, wsprintfW,
wsprintfA, sprintf, swprintf, _stprintf,
_snwprintf, _snprintf, _sntprintf, wvsprintf,
wvsprintfA, wvsprintfW, vsprintf, _vstprintf,
vswprintf, _vsnprintf, _vsnwprintf,
_vsntprintf, wvnsprintf, wvnsprintfA,
wvnsprintfW
strtok, _tcstok, wcstok, _mbstok
makepath, _tmakepath, _makepath,
_wmakepath, _splitpath, _tsplitpath,
_wsplitpath
scanf, wscanf, _tscanf, sscanf, swscanf,
_stscanf, snscanf, snwscanf, _sntscanf
_itoa, _itow, _i64toa, _i64tow, _ui64toa,
_ui64tot, _ui64tow, _ultoa, _ultot, _ultow
gets, _getts, _gettws
IsBadWritePtr, IsBadHugeWritePtr,
IsBadReadPtr, IsBadHugeReadPtr,
IsBadCodePtr, IsBadStringPtr
memcpy
PnP MS05-039
Zotob
CONFIGRET
ResDesToNtResource(
IN
PCVOID
ResourceData,
IN
RESOURCEID
ResourceType,
IN
ULONG
ResourceLen,
IN
PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes,
IN
ULONG
ulTag
)
{
case ResType_ClassSpecific: {
PCS_RESOURCE
pCsData = (PCS_RESOURCE)ResourceData;
LPBYTE
ptr = NULL;
ptr = (LPBYTE)((LPBYTE)pResDes +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
memcpy(ptr,
pCsData->CS_Header.CSD_Signature +
pCsData->CS_Header.CSD_LegacyDataOffset,
pCsData->CS_Header.CSD_LegacyDataSize);
PCT SChannel MS04-011
#define SSL2_MAX_CHALLENGE_LEN 32
typedef struct _Ssl2_Client_Hello {
DWORD
dwVer;
DWORD
cCipherSpecs;
DWORD
cbSessionID;
DWORD
cbChallenge;
UCHAR
SessionID[SSL3_SESSION_ID_LEN];
UCHAR
Challenge[SSL2_MAX_CHALLENGE_LEN];
Ssl2_Cipher_Kind CipherSpecs[MAX_UNI_CIPHERS];
} Ssl2_Client_Hello, * PSsl2_Client_Hello;
SP_STATUS Pct1SrvHandleUniHello(..., PSsl2_Client_Hello pHello,...) {
Pct1_Client_Hello ClientHello;
...
CopyMemory( ClientHello.Challenge,
pHello->Challenge,
pHello->cbChallenge);
NNTP MS05-030
HRESULT CNewsStore::OnResponse(LPNNTPRESPONSE pResponse) {
...
if (pResponse->state == NS_LIST)
hr = _HandleListResponse(pResponse, FALSE)
...
}
HRESULT CNewsStore::_HandleListResponse(LPNNTPRESPONSE pResp, BOOL fNew) {
LPSTR psz, pszCount;
int nSize;
char szGroupName[CCHMAX_FOLDER_NAME];
LPNNTPLIST pnl = &pResp->rList;
for (DWORD i = 0; i < pnl->cLines; i++, m_op.dwProgress++) {
psz = pnl->rgszLines[i];
while (*psz && !IsSpace(psz))
psz = CharNext(psz);
nSize = (int)(psz - pnl->rgszLines[i]);
if (nSize >= CCHMAX_FOLDER_NAME)
nSize = CCHMAX_FOLDER_NAME - 1;
CopyMemory(szGroupName,
pnl->rgszLines[i],
nSize);
Last Updated
20060103
LSASS MS04-011
Sasser
VOID DsRolepDebugDumpRoutine(
IN DWORD DebugFlag,
IN LPWSTR Format,
va_list arglist
) {
#define DsRolepDebugDumpRoutine_BUFFERSIZE 1024
WCHAR OutputBuffer[DsRolepDebugDumpRoutine_BUFFERSIZE];
...
length += (ULONG) wvsprintfW(&OutputBuffer[length],
Format,
arglist);
...
}
How Do you Find Them?
• #include <banned.h>
• C4996 warnings
The Replacements
•
•
•
•
Don’t use C++ as a glorified C!
Use std::string
Use strsafe.h
Use strcpy_s etc
Auto-replacement of Banned
Functions
• If the compiler knows the destination buffer
size at compile time, it can automatically
generate secure code
• Add the following to auto-migrate functions to
safe functions
• #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES (1)
char buf[32];
strcpy(buf,src);
char buf[32];
strcpy_s(buf,src,32);
But Isn’t C dead?
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
The Leap of Faith
• What about regressions?
• In ten years, I have seen only one regression at
Microsoft
Effectiveness?
• Over 25% of MSRC memory corruption vulns
did not affect newer products simply because
we banned the API(s) in question and replaced
them with a more secure version
• That’s low cost engineering at its best!
Pop Quiz
• What’s in an 8oz glass of wine?
• What’s in an 8oz glass of poison?
• What’s in an 8oz glass of wine with a drop of
poison?
Sin and Insecure Code
Righteous Man
+
One Sin
Well-Written Code
+ One Vulnerability
Sinful Man
Insecure System
All Sin is the Same …
• There is no “good” or “bad” sin, it’s all sin in
God’s eyes.
• There is no “Security Bulletin” scale for sin
Critical:
Important:
Moderate:
Low:
Adultery, Murder
Bearing False Witness
Stealing
Coveting
… but insecure Code is not the Same
• An anonymously accessible remote code
execution vulnerability that gives you root is
*way* worse than a local information
disclosure vuln accessibly only by admins
Critical:
Important:
Moderate:
Low:
Remote code execution
Server DoS
Temporary Server DoS
Client DoS
Banned APIs
• We have banned over 120 APIs at Microsoft
• They are great examples of “One-line” Sins
Removing Sin
• How do you remove Sin?
• By replacing Sin with something not Sinful!
• Easy to say, very hard to do.
• How do you remove banned APIs?
• By replacing them with something less
dangerous!
• Easy to say, easy to do.
And I know that nothing good lives in me, that is, in my sinful nature.
I want to do what is right, but I can't.
Romans 7:18
Removal takes a Leap of Faith
• Trust that God forgives your Sins
• Trust that the banned API replacements don’t
introduce regressions!
Praise the Lord, …
who forgives all your sins.
Psalm 103:3
How Do you Remove Banned APIs?
• Admit you have banned APIs (admit you sin!)
• Do something about it (admit the Lord into
your heart)
• Don’t repeat!
Banned APIs and the Sin Within
Summary
• Admit you sin
– In life and in code
• Do something about it
– Study Romans
– Remove Banned APIs
• Put steps in place to help prevent Sin and
banned APIs
– Think!!
– Use banned.h in all your C/C++ code
Questions!?

similar documents