WHOISMarkus(@marver)Headofresearch@x41D-SecSpeaksGermanNotCISSP
JP(@veorq)Principalresearcher@KudelskiSecuritySpeaksFrenchCryptoguy
2
AGENDASignalinternals,securitypromises
Attacksurfaceandliabilities
Bugs,alternativefeatures,anddemos
Conclusions
4
THESIGNALAPPSMobileappsformessaging&audio/videocalls
ByOpenWhisperSystems(MoxieMarlinspikeetal.)
Formerlyknownas"TextSecure","RedPhone"
Android,iOS,andChromeDesktopapp
6
TRUSTEDTOOLEndorsedbySnowdenandotheropinionleaders
PopularamongactivistsintheUSandabroad
MinimaldatacollectionfromSignalservers
7
SECURITYPROMISESSolidend-to-endencryption,defendingagainst
ActivenetworkattackersClientandservercompromisesTrafficanalysis(partially)
Highassurancesoftware,with
Codeperceivedashigh-qualityNomajorsecurityissueeverReproducibleAndroidbuilds
8
SIGNALISMORETHANSIGNALCorecrypto"libsignal"licensedtoandintegratedin
FacebookMessenger's"SecretConversations"mode
FacebookWhatsAppdefaultencryption
GoogleAllo's"Incognito"mode
9
KEYAGREEMENT:X3DH
Combines4keypairs:long-termandephemeral
One-timeprekeystrick,tosimulateonline-ness
Forward-secret,resilienttomaliciousservers
Out-of-bandidentityverificationnecessary 11
SESSIONKEYS:DOUBLERATCHET
Protocoltocomputemessage-uniquekeys:
NewDiffie-Hellmanforeveryfirstmessagefromaparty
"Key:=Hash(Key)"forconsecutivemessages
Pastandfuturemessagessafeifpresentkeyknown
Attachmentshaveidenticalprotection
12
THE"SIGNALPROTOCOL"=X3DHanddoubleratchetasimplementedinSignal
(MoxieMarlinspike,[email protected],30.11.16)
13
UNSPECIFIEDa.k.a."codeisdocumentation":
Howareattachmentsencrypted?Howareaudioandvideostreamsencrypted?Aretheyfullyintegritychecked?Howdoesgroupmessagingwork?
etc.
15
NETWORKARCHITECTURE
AttachmentsstoredonS3,ate.g.
MessagingserversrunbyOWS
https://whispersystems-textsecure-attachments.s3.amazonaws.com
16
CODEBASE(CLIENT-SIDE)Mainreposfrom :
libsignal-service-java(~20klocJava)
libsignal-protocol-java(~20klocJava)
Signal-Android(JNI+~60klocJava)
libsignal-protocol-c(~30klocC)
SignalServiceKit(~20klocObj-C)
Signal-iOS(~25klocObj-C)
https://github.com/whisperSystems
17
PREVIOUSRESEARCHNopublicrecordofmajorsecuritybug
Minorsecurityissuesfixed(seetracker)
Formalanalysisoftheprotocol(Cohn-Gordonetal.)
Keycompromiseimpersonation,replay(Kobeissietal.)
19
THENETWORKATTACKER
Goal:compromisesecrecy,impersonatelegitpeer
Caninject/modifymessageswithinX3DH,doubleratchet
Cansabotageprekeys(invalidvalueorformat,etc.) 21
THEMALICIOUSPEER
Goal:ownotherpeer(s)
Gotkeys,cantrigger/abuseparsingoftext/mediadata
Morepowerfulthanthenetworkattacker
Oftenoverlooked22
THIRD-PARTYCODEAndroid:500klocofCetc.(WebRTC,OpenSSL)
iOS:~60klocofObj-CandC(speexcodec,DSP,etc.)
Both:OScomponentstodecodeimages,low-levelstuff
Crypto:curve25519-donna.c,JavaSDKcrypto
24
MISSINGMITIGATIONSANDINSECUREDEFAULTS
NosandboxingonAndroidnoriOS
HardwarekeystorenotusedonAndroid
Parsingofmediafilesfromuntrustedsources
DependencyoniOS/Androidmedialibraries
25
UNREALISTICSECURITYMODEL?"Break-inrecovery"protectsagainstanattackerthatextractstemporarykeys...butonlycertainkeys:
Securityrecoveredifa"KDFkey"leak
Recoveryimpossibleifa"rootKDFkey"leaks(CansilentlyMitM,asSteveThomastweeted)
Butkeysareallinthesamememoryregion...
Doesthismodelmakeanysenseonmobile?28
METHODOLOGYMulti-levelholisticapproachtobugdiscovery:
Machinelearning-guidedfuzzing
Cloud-basedparallelconcolicexecution
State-machinemeta-modelformalverification
Differentialcryptanalysisusingsyscallsassidechannels
Blockchainsmartcontractstorecordvulnsfound
(Releasingourtool,freeforcommercialuseonly) 30
SERIOUSLYNorigorousprocess
Noautomationorfuzzing
Weonlysuperficiallyreviewed:
Obvioususerinput,protocoledgecasesCommonsoftwarebugclassesClientcode,notservercodeMessagingprotocol/code,notcalling
32
TOOLSETiPhones,rootedAndroids,Chromeextension
SignalserviceCLI(tocontrolwhatissenttotheserver/peers)
PythonMitM'ingtools
https://github.com/AsamK/signal-cli
33
MACBYPASS(ANDROID)
64-bit(long)file.length()castto32-bit(int)
file.length()=X+4GB=>remainingData=X
MACcomputedoverfirstXbytes=>extra4GBcanbesettoarbitraryvaluesandpasstheMACverification
34
MACBYPASS:BASICEXPLOITATION
MitMfromS3,whereattachmentsarestored:
Awaitarequesttofetchanattachment
Padtheattachmentwith4GB+useHTTPcompression
=>Dataattachedtooriginaldataunnoticed
W/AttachmentDownloadJob(10484):Causedby:javax.crypto.BadPaddingException:EVP_CipherFinal_exatcom.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(NativeMethod)atcom.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430)atcom.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:490)
35
MACBYPASS:MOREEXPLOITATION
Problem:decryptionkeyisunknown,socan'tforgemeaningfulciphertextblocks..
Orcanwe?ExploitmalleabilityofCBCmode
CBCdecryption:P[i]=Dec(C[i])⊕P[i-1]
Know/guessoneDec(C[i]),chooseP[i-1]
Controleveryotherplaintextblock!36
MACBYPASS:DEMOBlindmessagerepetition
Playbackisn'tsupportedonthisdevice.
SignalMessenger-MACBypass-RepeatingAudio
0:00/0:23
38
MACBYPASSKnownplaintextforgery
Playbackisn'tsupportedonthisdevice.
SignalMessenger-MACBypass-TamperAVoiceMessage
0:00/1:10
39
NOPUBLICKEYVALIDATIONECDH:private-key×public-key=shared-secret
Ifpublic-key=0,thenshared-secret=0
Suchinvalidpublickeysshouldnotbeaccepted
Signalacceptspublic-key=0
40
IMPACTOFINVALIDKEYSYoucanforceallpeerstosendyoumessagesencryptedusinganall-zerokey(thus,essentiallyincleartext)
Deniability("PRNGbug!")
Killsbreak-inrecovery
41
CLIBCALLBACKSClibsignalusersneedtodefinecallbackssuchasencrypt_func(),usedtoencryptstuff(pretty
important)
Youneedtodefinethecallbacks,butlibsignaltriesto
intsignal_encrypt(signal_context*context,signal_buffer**output,intcipher,constuint8_t*key,size_tkey_len,constuint8_t*iv,size_tiv_len,constuint8_t*plaintext,size_tplaintext_len){assert(context);assert(context->crypto_provider.encrypt_func);returncontext->crypto_provider.encrypt_func(output,cipher,key,key_len,iv,iv_len,plaintext,plaintext_len,context->crypto_provider.user_data);}
42
CLIBCALLBACKSUnittestsprovideexampleimplementations,for
exampletouseOpenSSLtoencryptstuffinencrypt_func()
inttest_encrypt(signal_buffer**output,intcipher,constuint8_t*key,size_tkey_len,constuint8_t*iv,size_tiv_len,constuint8_t*plaintext,size_tplaintext_len,void*user_data){intresult=0;uint8_t*out_buf=0;
constEVP_CIPHER*evp_cipher=aes_cipher(cipher,key_len);if(!evp_cipher){fprintf(stderr,"invalidAESmodeorkeysize:%zu\n",key_len);returnSG_ERR_UNKNOWN;} 43
BUGSINEXAMPLECALLBACKSBugsintest_encrypt():
Typeconfusion=>crashforcertainmessages(64-bit)
Integeroverflow+potentialheapoverflow(32-bit)
44
RTPPACKETSUNDERFLOWWhenpacketLen<sizeof(RtpHeader),payloadLen
isnegative=>out-of-boundreadinHMAC
Seemsunexploitable...
RtpPacket*RtpAudioReceiver::receive(char*encodedData,intencodedDataLen){intreceived=recv(socketFd,encodedData,encodedDataLen,0);
if(received==-1){__android_log_print(ANDROID_LOG_WARN,TAG,"recv()failed!");returnNULL;}
RtpPacket*packet=newRtpPacket(encodedData,received);...RtpPacket::RtpPacket(char*packetBuf,intpacketLen){packet=(char*)malloc(packetLen);//1.INTEGERUNDERFLOWpayloadLen=packetLen-sizeof(RtpHeader);memcpy(packet,packetBuf,packetLen);}
45
CRASHYIMAGESSignaluseslibskiaformediadecoding
Bugsinlibskia...
Can'tdisablemediafilesparsinginSignal
Whatcanwrong?
46
DEMOCRASH
Playbackisn'tsupportedonthisdevice.
Signalbootloop(rebootroot-causeNOTinSignal)
0:00/0:45
47
THEEVERLASTINGPREKEYKeyagreementusesone-timeprekeys
Exceptforthe"last-resort"key
FallbackmechanismagainstDoS
packageorg.whispersystems.libsignal.util;
publicclassMedium{publicstaticintMAX_VALUE=0xFFFFFF;}
publicbyte[]decrypt(PreKeySignalMessageciphertext,DecryptionCallbackcallback)throwsDuplicateMessageException,LegacyMessageException,InvalidMessageException,InvalidKeyIdException,InvalidKeyException,UntrustedIdentityException{...if(unsignedPreKeyId.isPresent()){ 49
X3DHKEYAGREEMENTAlicefetchesBob'sidkeyandprekeyfromserver...
Computessharedsecret,encryptsamessage,sendswithpubkeys...
Bobcomputessharedsecret,decryptsthemessage...
Prekeyremovedfromtheserver,exceptifit'sthelastresortkey(afterallprekeyshavebeenused)
50
PREKEYMESSAGESTRUCTURE
MessageisabundleofaPreKeySignalMessageandanencryptedmessage(WhisperKeyMessage)
51
DEFENSESAGAINSTREPLAYBobwon'tdonewkeyagreementforknownbasekeys
Createfakesessionstatesandexhaustthestatelimit
Avalidciphertextisneeded(withavalidMAC)
Piggybackonmessagesfromadifferentsession
53
WHYREPLAYISPOSSIBLEKeyexchangeandciphertextscanbereplayed
because:
Bobdoesnotcheckiftheencryptedmessagebelongstotheprekeypartofthemessage
Prekeymessagesarenotintegritychecked,soaMiTMcancreatearbitrarysessionstates
Limitof40sessionstates,oldoneswillbepurged
54
HOWTOREPLAY1. ExhaustBob'sprekeys(e.g."evilbackend"deletes
normalprekeys)2. LetAlicecreateasessionwiththelastresortkey3. RecordAlice'sfirstmessage(s)4. Replay!(evenafterBobcomputesnewprekeys)
55
AUDIOFILESERVERONLOCALHOST
IfyouplayanaudiofilethatwassenttoyouanopenHTTP-Serverisstartedonlocalhost
Random16byteURI,randomport
Notadirectproblem(unlessportandURIinfoleaks)
57
MORE?
Lookedatityesterdaymorning...
Greaterriskof"friendlyfire"(©Justin)CancoercepeersintousingK≡0?
58