In ASP.Net MVC a common technique when dropdowns and textboxes are required to be disabled but their values still need posting back is to include a hidden backing field corresponding to the same model property. In the case of CheckBoxFor the idea is the same, except there is one extra peculiarity with CheckBoxFor due to the fact that for this HMTL helper MVC renders a hidden text field of its own (along with the checkbox) which does not have the disabled attribute even if you have added it to the main CheckBoxFor HTML Helper. For example here is what is rendered for a disabled checkbox whose underlying bool property is set to true.
As nothing gets sent to the server if the checkbox is not checked, the binder has nothing to bind to so MVC always renders this hidden field and always sets its value to false. Due to the fact it appears after the checkbox, the true from the checkbox will bind first if the user has checked it, as MVC always binds to the first matched property. Therefore when we are dealing with disabled but checked checkboxes and we want to post the value, we need to ensure our hidden field appears before the @Html.CheckBoxFor hidden field. The first image below for example always bind as false (even though the checkbox is checked), while the second one binds are true.
I think this is a common enough problem, so hopefully the above helps.
Credit to Darin Dimitrov for his answer on stackoverflow which outlines the approach above, however crucially he does not mention the importance of having the backing field before the @Html.CheckBoxFor statement which is why I imagine some people mentioned in the comments that a hidden backing field did not work for them.