#571 Dialback secrets have very low entropy

Reporter Thijs Alkemade
Owner Zash
Stars ★★ (2)
  • Milestone-0.9
  • Priority-High
  • Type-Defect
  • Security
  • Status-Fixed
  1. Thijs Alkemade on

    I was looking at https://hg.prosody.im/0.9/file/f755e0bdc60a/util/uuid.lua and wondering what happens after the server has just restarted. The sources of entropy it uses are: * The current UNIX time (os.time()) * The CPU time used by Prosody (os.clock()) * tostring({}) The initial seed is determined by concatenating all of these and then calling SHA1, e.g.: sha1("14486099260.02table: 0x1f85920") * The exact second the server restarted is easy to observe, for example with XEP-0012. There may be some clock drift, but the number of values we need to check probably doesn't exceed 2^6. * While testing the CPU time used by Prosody the first time util.uuid is included, I only observed values between 0.01 and 0.04 (with no extra decimal places), probably as it's one of the first things Prosody does. Lets say this has about 2^3 different values we need to try. * This one is harder. To estimate this, here are the values used for the initial seed for 20 starts of Prosody (on 64-bits Linux, no luajit): 0x25d9500 0x22cd920 0x1cee920 0x1c28920 0x1c1f920 0x1991500 0x18d7500 0x1819920 0x17cc500 0x166c920 0x1394920 0x1385920 0x136a920 0x131c920 0x11d2500 0x11b0920 0xde4920 0xca0920 0xbed500 0x800500 If we assume that this is a random number from the range 0x0000000 - 0x4000000 which always ends in 0x20 or 0x00 then this can take about 2^19 different values. So all of this together means we have about 28 bits of entropy for the initial seed. The very first UUID generated by Prosody (without extra plugins) is generated here: https://hg.prosody.im/0.9/file/f755e0bdc60a/core/hostmanager.lua#l77 Which is used: https://hg.prosody.im/0.9/file/f755e0bdc60a/plugins/mod_dialback.lua#l21 Obtaining the dialback secret of a server would allow an attacker to impersonate that server. An attacker with their own domain can carry out a normal dialback with the target server and use the dialback key that was used to brute-force that server's secret. After that they can impersonate the domain without having to spoof DNS. Estimating based on `openssl speed` on my laptop suggests 2^28 SHA1 calls would take about 72 seconds on my machine.

  2. Zash on

    So, on *nix we can try to open /dev/urandom and a) seed the thing from that or b) just map random.bytes to urandom:read, possibly with some buffering. Other platforms (read: Windows) are trickier. Using the OpenSSL random subsystem is one way. One could also extract some random on shutdown and read it back on startup, which would limit this to the first startup (assuming util.random isn't terrible when seeded properly).

    • tag Status-Accepted
    • tag Milestone-0.9
  3. Zash on

    Fixed and released in 0.9.9. Thanks a lot for reporting!

    • owner MattJ
    • tag -Hidden
    • tag Status-Fixed
  4. Zash on

    • owner Zash

New comment

Not published. Used for spam prevention and optional update notifications.