bitcoind Timing leak in RPC authentication

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


CVSS Base Score: 5/10
Impact Subscore: 2.9/10
Exploitability Subscore: 10/10
Exploit range: Remote
Attack complexity: Low
Authentication: No required
Confidentiality impact: Partial
Integrity impact: None
Availability impact: None

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/

References:

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