bitcoind Timing leak in RPC authentication

2013-07-24 / 2013-07-26
Credit: pakt
Risk: Low
Local: No
Remote: Yes
CWE: N/A


Ogólna skala CVSS: 5/10
Znaczenie: 2.9/10
Łatwość wykorzystania: 10/10
Wymagany dostęp: Zdalny
Złożoność ataku: Niska
Autoryzacja: Nie wymagana
Wpływ na poufność: Częściowy
Wpływ na integralność: Brak
Wpływ na dostępność: Brak

bool HTTPAuthorized(map<string, string>& mapHeaders) { string strAuth = mapHeaders["authorization"]; if (strAuth.substr(0,6) != "Basic ") return false; string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); string strUserPass = DecodeBase64(strUserPass64); return strUserPass == strRPCUserColonPass; } Last string comparision strUserPass == strRPCUserColonPass gets compiled to: do { if ( !len ) break; less = *(_BYTE *)strUserPass < *(_BYTE *)strRPCUserColonPass; eq = *(_BYTE *)strUserPass++ == *(_BYTE *)strRPCUserColonPass++; --len; } while ( eq ); which is a byte-by-byte compare. Attacker with precise clock (being in the same LAN, for example) might learn the RPC password letter by letter, by trying passwords like 'a...", "b...", "c..." and observing which took the longest time to verify. This code in bitcoinrpc.cpp: if (mapArgs["-rpcpassword"].size() < 20) MilliSleep(250); protects from bruteforce for short password. Unfortunately, when run, bitcoind suggest a 32 chars password. Paradoxically short passwords are safer to use than longer ones, wrt to the timing leak. Here's an example of time independent array comparison: http://rdist.root.org/2010/01/07/timing-independent-array-comparison/

Referencje:

https://github.com/bitcoin/bitcoin/issues/2838


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top