Assuming the operating system allocates pages completely randomly, my best calculation says that there's about a 11% chance that any given victim address will have at least 12 matching pages in your 4MB buffer. That's not very likely, and certainly doesn't agree with the 70% success rate you saw.
However, there are good reasons for an operating system to avoid mapping pages randomly, and instead to try its best to map contiguous pages. One reason for this is that the OS sometimes needs to allocate large contiguous buffers (to support huge pages or large DMA buffers, for example), and random allocation of physical pages would make it really hard to find a large enough region. This is known as memory fragmentation.
But in the context of this discussion, a more interesting benefit of contiguous allocation is (ironically enough) the level-3 cache performance. If you're running an algorithm that uses a large memory buffer, the way to get the best performance is to allocate contiguous physical memory, so that the individual pages don't evict each other from the cache. If the OS succeeds in maximizing performance this way, then it will also succeed in maximizing the attack's effectiveness: your 4MB buffer will cover the entire cache, and you'll have a 100% chance of evicting a victim page. So your observed 70% success rate is less a measure of chance, and more a rough measure of how effective the OS is at allocating pages for good cache performance.
If you want to see an example of an OS working this way in practice, read about Linux's buddy allocator. It starts by breaking memory into a set of large free blocks. Then, if it wants to allocate a page, it takes one of those large blocks and splits it in half. It then takes one of the halves and splits it in half again, and continues until it's got a pair of 1-page-sized block -- at which point it's also got one 2-page-sized block, one 4-sized, one 8-sized, etc. The first two allocations will be those two 1-page blocks, which are right next to each other because they are the result of breaking a 2-page block in half. The third allocation will break the other 2-page block in half, which again will be next to the other two for the same reasons.
So whenever it needs a new page, the allocator takes the smallest block it can find and breaks it down until it's got a single page. Finally, when a page is freed, the allocator checks to see if there is a free page right next to it, so it can form those two pages back into a larger block. The net effect is to keep allocations roughly contiguous when possible.