Heartbleed TLS Heartbeat Protocol...• Failure of the OpenSSL library to validate the heartbeat...
Transcript of Heartbleed TLS Heartbeat Protocol...• Failure of the OpenSSL library to validate the heartbeat...
DealingwithCodeThatIsOpaquetoSta7cAnalysis
BartonP.Miller†‡,JamesA.Kupsch†‡,ElisaHeymann†*,VamshiBasupalli†‡
NISTWorkshoponSoEwareMeasuresandMetricstoReduceSecurityVulnerabiliJes
Gaithersburg,MDJuly12,2016
†ComputerSciencesDepartment,UniversityofWisconsin‡DHSSoEwareAssuranceMarketplace(SWAMP)
*AutonomousUniversityofBarcelona
RecentExperience
• ReviewedhighprofilevulnerabiliJes– Heartbleed(CVE-2014-010)– glibcDNSresolver(CVE-2015-7547)
• Obtainedvulnerablesourcecode• RanstaJccodeanalysistoolsoneach• Toolsfailedtofindthebugs• Bugwasopaquetothetools
2
HeartbleedAtit’sheart(sorry),it’sjustabufferoverflow…• FailureoftheOpenSSLlibrarytovalidatetheheartbeatpacket
lengthfield(ascomparedtothesizeoftheactualmessage).• HeartbeatpacketsarecontainedwithinTLSpackets.• Theheartbeatprotocolissupposedtoechobackthedatasentinthe
requestwheretheamountisgivenbythepayloadlength.• Sincethelengthfieldisnotchecked,memcpycanreadupto64KB
ofmemory.
memcpy(bp, pl, payload); Lengthfield.Suppliedbyanuntrustedsource.
Source.Bufferwiththeheartbeatrecord.Improperlyused.
DesJnaJon.Allocated,used,andfreed.OK.
3
TLSHeartbeatProtocol
4
type version len message
type len payload padding
Recordbuffer(allocatedbymalloc) ~16KB
TLSrecord
Heartbeatmessage
Illegallylargemessagelenallowsreading~64KB
Lenisthenumberofbytesofthepayload.Shouldbeconstrainedbythetotal
messagelength,header(3),andminimalpadding(16)
Lenisthetotalmessagelengthinbytes
Validread
5
Heartbleed
Addedlengthchecktoremediate:
if (1+2+payload+16 > s->s3->rrec.length) return 0 // silently discard
Andnoneofthecurrenttoolscouldfinetheproblem…why?
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
6
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
1.Findtheheartbeatpacketinthe(untrusted)userrequest
7
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
2.Extractuser-statedpayloadlengthoftheheartbeatpacket
8
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
3.plisanaliastotheheartbeatpayloadstartaddress.
9
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
4.LengthofTLSpacketthatcontainsheartbeatpacket
10
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
5.payloadlengthshouldbe≤TLSrecordlength-19
11
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
6.allocateenoughmemoryforechopacket(accordinguserpayload)
12
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
7.Copyheartbeatdatabasedonthelengththeyclaimed.Canalsograb
othernearbydata.
13
2556 unsigned char *p = &s->s3->rrec.data[0], *pl;
2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) { 2573 unsigned char *buffer, *bp; 2574 int r;
2580 buffer = OPENSSL_malloc(1+2+payload+padding); 2581 bp = buffer;
2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
Here’stheoffendingcode,slightlyredacted
Needtoactuallyknowthatpayloadlengthisnottrusted(tainted)data.
14
HeartbleedConceptually,thisisjustanexerciseintaintanalysis.WeneedtofollowingtheoriginalenclosingTLSpacketfromasocket,markingitastainted.Beforedisclosure:– Notoolswetriedfoundthebug– Notoolsweknowoffoundthebug
Coverity“fixed”theirtoolbynoJngthatextracJngtheintegerpayloadlengthfromanetworkbyte-orderusesabyte-swapinstrucJononaliqleendianmachine,andsuchaswapinstrucJonisrareenoughthatthisisasignthatthedatacomesfromthenetwork.
GrammaTechcoulddothetaintanalysisstarJngatsocketbuffers,butdidn’tdoitbecauseitwastooslowinpracJce.Whentheyturneditonfortherightsec.onofcode,itfoundtheproblem.
15
Difficul7esforSCATools
• Legacylanguagesinherentfeatures– Rawmemoryaccess– Lackoftypesafety– Manualresourcemanagement– PointersandpointerarithmeJc
• Codecomplexity– IndirecJon– Largeprogramstate– Complexcontrolflow
16
WhySCAToolFailtoReport
• NotdeducingaccuratesetofvaluesorproperJes(tainted,iniJalized,notnull,…)forvariables
• NotdeducingcorrelaJonbetweenvariables• UsingheurisJcstodeterminelikelyvaluesorproperJes
• UncertainresultsnotreportedtoreducefalseposiJves
• Confidencescoremaypointtoopaquecode,ifthereisareport
• Fornon-reports,nowaytoconveyconfidence17
DynamicAnalysisTools
• DynamicanalysisdidfindHeartbleed(singlefuzzedpacketcouldexposethevulnerability)
• WedonotknowofanydynamicanalysistoolsthatfoundfoundglibcDNSvulnerability
• DifficulJes:– GeneraJngcorrectbadinputsequence– Inputdataspaceislarge– Inputdatasequenceiscomplex
18
Goal:LessOpaqueCodeforSCA
• Twoapproaches– Newcode:
• Usemodernlanguagestopreventssomedefects– D,Rust,modernC++
• Use(more)analyzablesubsetoflanguage– MISRA– CheckedC– C++CoreGuidelines,GSL(guidelinesupportlibrary),andSCA
– Legacycode(andtoalesserextentnewcode):• IdenJfypartsthatareopaque• CurrentmetricsdonotidenJfyopaquecode
19
CommonMetrics
• MetricTypes– Simplecounts:
• Lexicalelements:linesofcode,comments,…• SyntacJcelements:parameters,types,operators,…• PerfuncJon,file,orcodebase
– Calculatedmetrics:• Examples:CyclomaJc,Halsted• PerfuncJon
– RelaJonshipsbetweenfuncJons,classes,…• Examples:Coupling,Cohesion,Connascence• PerpairoffuncJons,classes,…
• Inourexperience,thesemetricsdidnotcorrelatewithweaknessesorstaJcanalyzability
• Focus:costtodevelop,maintain,test,enhance,…
20
Proposal:OpaquenessMetric
• DeveloptoolsthatidenJfyprogramcomplexityintermsofopaquenesstoanalyzabilitybySCAtools– SemanJccomplexityofcodethatreachesatool'sabilitytoreportduetoreachinglimitsoftheanalysisalgorithm's
• Decidability• ImplementaJon
– Scoreregionsofthesourcecodewithanopaquenessscore– AlsoincluderaJonaleforpoorlyscoringregions
• ProvideprescripJveadvicetotransformthecodetobelessopaquetoSCA(moreeasilyandcorrectlyanalyzable)
21
SCAToolProvidersPathForward
• BestsemanJccodeanalysisisincommercialtools• SCAtoolsalreadyhavemuchoftheinformaJon
– KnowwhereassumpJonsaremade– LocaJonofassumpJonsareaccurate– Shouldbeaccurateforusersofthetool
• LimitaJons– Inherentlynotintheirinterest,reporJnglimitaJonsisbadformarkeJng
– Specifictothetypesofproblemsthetoolfindsandthepowerofthetool
22
BroaderPathForward:DevelopTool
– StartwithexisJngopensourceanalysisframework• ClangStaJcAnalyzer• Gcc
– FundopensourcetoolbasedonframeworktoscorethesourcecodebasedonitsopaquenesstostaJcanalysis
– DevelopprescripJveguidanceontransformingsourcetomakecodelessopaque
23
Ques7ons
24